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-jcache
。 Infinispan 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。
在 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-jcache
。 Infinispan 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。