Confluence includes a caching API atlassian-cache
that should be used instead of custom cache solutions.
The provided API:
This page describes how to use the atlassian-cache
APIs.
atlassian-cache
APIs usageThe following code block is a short example of some code using the atlassian-cache
APIs.
1 2import org.apache.commons.lang3.StringUtils; import com.atlassian.cache.Cache; import com.atlassian.cache.CacheLoader; import com.atlassian.cache.CacheManager; import com.atlassian.cache.CacheSettingsBuilder; import com.atlassian.plugin.spring.scanner.annotation.component.Scanned; import com.atlassian.plugin.spring.scanner.annotation.imports.ConfluenceImport; import javax.annotation.Nonnull; // some imports omitted for clarity @Scanned public class ListPagesMacro implements Macro { private final Cache<String, String> cache; @ConfluenceImport private final PageManager pageManager; public ListPagesMacro(@ConfluenceImport CacheManager cacheManager, PageManager pageManager) { this.pageManager = pageManager; cache = cacheManager.getCache(ListPagesMacro.class.getName() + ".cache", new ListPagesCacheLoader(), new CacheSettingsBuilder().expireAfterAccess(30, TimeUnit.MINUTES).build()); } @Override public String execute(Map<String, String> parameters, String body, ConversionContext context) throws MacroExecutionException { String spaceKey = parameters.get("spaceKey"); if (StringUtils.isBlank(spaceKey)) spaceKey = context.getSpaceKey(); if (StringUtils.isBlank(spaceKey)) throw new MacroExecutionException("A spaceKey is required."); // if the spaceKey is not present in the cache then the ListPagesCacheLoader will create the value as // implemented in the 'load' method and it will be populated into the cache automatically. return cache.get(spaceKey); } // The loader class used to populate a cache entry on cache miss. private class ListPagesCacheLoader implements CacheLoader<String, String> { @Override public String load(@Nonnull String spaceKey) { return renderPageList(spaceKey); } } String renderPageList(String spaceKey) { // implementation goes here } ... }
To use the Atlassian Cache API, you first need to get a CacheManager injected into your component (macro, action, etc.). To do this, add a setter or constructor parameter to your component, depending on whether you are using setter-based or constructor-based dependency injection.
To retrieve a cache from the cache manager, use a cache key that is unique to your plugin.
We recommend using the fully qualified name of the class that uses the cache, plus a name that describes the contents
of the cache.
The returned Cache has an API very similar to Java Map
.
To store a value in the cache, call put(Object, Object)
and get(Object)
to look up a previously stored value.
In a single instance of Confluence, you can store any objects in the cache.
In a clustered instance, you can only store keys and values that implement Serializable
.
Always depend on CacheManager
instead of its super-interface CacheFactory.
CacheFactory
exported by Confluence is an instance of TransactionalCacheFactory
with often surprising performance characteristics.
If you don't specify a cache configuration explicitly, then it is determined by Confluence by default, with the ability for the Confluence administrator to change the settings at runtime.
The default expiry is one hour and the cache will store up to 1000 items. If space is needed for new items, the least-recently used items will be automatically expired or removed. However, it is preferable to create a cache specifically configured to the plugin requirements.
To avoid consuming excessive amounts of memory, you should always try and set an expiry policy on the caches you create. A timed base expiry is most appropriate for most applications. It is usually very difficult to determine an appropriate number of cache entries that suits clients at all scales.
Rate this page: