有没有一种简单的方法可以将Spring的@Cacheable
注解与非单例(例如:session-scoped)bean,并该高速缓存具有与所述bean相同的作用域?
示例如下:
import javax.inject.Inject;
import javax.inject.Named;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Scope;
import org.springframework.security.core.context.SecurityContextHolder;
@Named
@Scope("session")
public class UserNameRetriever {
@Inject private UserDao userDao;
@Cacheable("userName")
public String getUserName() {
return userDao.getUserByLogin((String)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getName();
}
}
字符串
理想情况下,UserNameRetriever.getUserName()
将在每个会话中从UserDao
获取用户名一次,但这段代码实际上是在应用程序范围内缓存的。
4条答案
按热度按时间0h4hbjxa1#
如果需要会话缓存,请使用会话。也就是说,将用户存储在会话作用域bean的私有字段中,或者直接访问
HttpSession
对象。@Cacheable
通常用于应用程序范围的资源。当然,您可以使用
key="#user.id"
,并在@PreDestroy
方法上该高速缓存无效(手动或使用@CacheEvict
),但最好不要将两者混合在一起-缓存和会话数据。f8rj6qna2#
我还没有尝试过,但根据Spring参考,我认为这可以工作:
字符串
hiz5n14c3#
我认为你从错误的Angular 来处理这个问题。与只存储一个值的“local”会话范围缓存不同,它有一个全局缓存,用于存储从用户名到
User
值的Map。在本例中,将
@Cacheable
放在getUserName()
上,然后将其放在UserDao
上:字符串
这不仅是缓存的惯用用法,而且将证明它更容易维护和更好的性能。
回到你最初的问题:不,这是不可能的开箱即用。您必须编写自己的
CacheManager
-可能是围绕现有实现编写的decorator。t0ybt7op4#
您可以创建带有Session(如果您只希望用于请求)范围的CacheManagerbean。它工作得很好。
字符串
考虑限制/设置缓存的边界(正如一些ppl提到的内存“泄漏”),所以你可以尝试使用CaffeineCacheManager,在那里你可以设置最大大小,过期ttl等。