WildFly 11/Java EE 7/JSR 107:缓存 - 缓存信息并让它自动过期的最佳方式是什么?

WildFly 11/Java EE 7/JSR 107: caching - what's the best way to cache information and let it expire automatically?

在 Java EE/WebApp 容器中存储数据片段并让它自动过期的推荐方法是什么?我可以使用会话持久性机制,但我的 http 会话通常比我希望保留的那些信息要长很多。

JavaEE 7 或 CDI 是否提供了一些东西? JCache 规范 JSR 107 的一些初步变体?还有其他好的解决方案吗?

我不确定这是 "best" 方式,但我一直在 Wildfly 中使用 Google Guava cache(8 到 10,但希望仍然适用)。对我来说,由于身份验证服务器非常慢,我正在缓存 Oauth 令牌。我的代码看起来像:

private static LoadingCache<String, MyPrincipal> tokenCacheMap;

@PostConstruct
private void postConstruct() {
    tokenCacheMap = CacheBuilder.newBuilder()
            .expireAfterAccess(15, TimeUnit.MINUTES)
            .build(
                    new CacheLoader<String, MyUserPrincipal>() {
                        @Override
                        public MyUserPrincipal load(String token) {
                            MyUserPrincipal myUserPrincipal = getUserFromToken(token);

                            if( myUserPrincipal != null ) {
                                myUserPrincipal.setToken(token);
                                return myUserPrincipal;
                            }

                            throw new SecurityException("token is not valid");
                        }
                    }
            );
}

//
// later in the code...
//
MyUserPrincipal myUserPrincipal = tokenCacheMap.get(token);

基本上,它所做的是设置一个缓存,让令牌在其中存活 15 分钟。如果需要,将调用 load() 方法以获取身份验证令牌和用户。缓存根据需要延迟填充 - 第一次调用会有获取令牌的开销,但之后它全部在内存中。

还有其他选项,例如,根据缓存中的项目数逐出旧信息。文档非常好,应该可以帮助您。

缺点是这不是 JEE 标准,但它过去对我有用。

如果您想使用 JCache API,您可以使用 infinispan-jcacheInfinispan is a scalable, highly available key/value data store included in WildFly.

To use it,将infinispan-jcache添加到pom.xml

<dependency>
    <groupId>org.infinispan</groupId>
    <artifactId>infinispan-jcache</artifactId>
    <version>...</version> <!-- e.g. 9.1.4.Final -->
</dependency>

并访问缓存 as follows:

import javax.cache.Cache;
import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.cache.configuration.CompleteConfiguration;
import javax.cache.configuration.MutableConfiguration;
import javax.cache.expiry.CreatedExpiryPolicy;
import javax.cache.expiry.Duration;
import javax.cache.spi.CachingProvider;
import java.util.concurrent.TimeUnit;

...

// Construct a simple local cache manager with default configuration
// and default expiry time of 5 minutes.
CacheManager cacheManager = Caching.getCachingProvider().getCacheManager();
CompleteConfiguration<String, String> configuration = new 
MutableConfiguration<String, String>()
            .setTypes(String.class, String.class)
            .setExpiryPolicyFactory(factoryOf(new CreatedExpiryPolicy(
                    new Duration(TimeUnit.MINUTES, 5))));

// Create a cache using the supplied configuration.
Cache<String, String> cache = cacheManager.createCache("myCache", configuration);

// Store a value, the entry will expire in 2 seconds.
cache.put("key", "value", 2, TimeUnit.SECONDS);
// Retrieve the value and print it out.
System.out.printf("key = %s\n", cache.get("key"));

// Stop the cache manager and release all resources,
// use try-with-resources in real code.
cacheManager.close();

请注意,Infinispan 有 great docs