简体   繁体   English

Spring的@Cacheable注释是否与注释方法的bean具有相同的范围?

[英]Can Spring's @Cacheable annotation have the same scope as the annotated method's bean?

Is there an easy way to use Spring's @Cacheable annotation with a non-singleton (eg session-scoped) bean and have the cache have the same scope as said bean? 是否有一种简单的方法可以将Spring的@Cacheable注释与非单例(例如会话范围的)bean一起使用,并且缓存与所述bean具有相同的范围?

Example: 例:

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();
    }

}

Ideally, UserNameRetriever.getUserName() would fetch the username from the UserDao once per session, but this code actually caches application-wide. 理想情况下, UserNameRetriever.getUserName()会在每个会话中从UserDao一次用户名,但此代码实际上会缓存应用程序范围内的用户名。

If you want a session cache, use the session. 如果需要会话缓存,请使用会话。 That is, store the user in a private field in the session-scoped bean, or access the HttpSession object directly. 也就是说,将用户存储在会话范围的bean中的私有字段中,或直接访问HttpSession对象。 @Cacheable is generally meant for application-wide resources. @Cacheable通常用于应用程序范围的资源。

Well, you can use key="#user.id" , and to invalidate the cache (manually or with @CacheEvict ) on a @PreDestroy method, but it would be better if you don't mix the two - caching and session data. 好吧,你可以使用key="#user.id" ,并在@PreDestroy方法上使缓存(手动或使用@CacheEvict )无效,但如果你不混合两个 - 缓存和会话数据会更好。

I think you are approaching the problem from the wrong side. 我认为你是从错误的一方接近问题。 Instead of having " local " session-scoped caches storing only one value have one global cache storing a map from user name to User values. 不是存储仅存储一个值的“ 本地 ”会话范围的缓存,而是具有一个全局缓存,其存储从用户名到User值的映射。

In your case drop @Cacheable on getUserName() and put it on UserDao : 在你的情况下,在getUserName()上删除@Cacheable并将其放在UserDao

public class UserDao {
  @Cacheable("users")
  public User getUserByLogin(String user) {
    //...
  }
}

Not only this is more idiomatic usage of cache, but also it will prove to be easier to maintain and better performing. 这不仅是缓存的惯用用法,而且它将更容易维护和更好的性能。

Back to your original question: no, this is not possible out-of-the-box. 回到原来的问题:不,这不是开箱即用的。 You would have to write your own CacheManager - probably a around existing implementation. 您必须编写自己的CacheManager - 可能是围绕现有实现的

我没有尝试过,但根据Spring参考,我认为这样可行:

@Cacheable(value = "userName", key = "#root.target")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring 的 Cacheable Annotation 如何为通过 new 关键字初始化的类工作。 (在类构造函数中,通过 Bean 初始化) - How Spring's Cacheable Annotation can work for class initailized through new Keyword. (In a Class Constructor, initialized through Bean) Spring @Cacheable注解用于不同服务中的相同方法 - Spring @Cacheable annotation for same method in different service 调用使用@Cacheable注释的方法(org.springframework.cache.annotation.Cacheable) - Calling a method annotated with @Cacheable (org.springframework.cache.annotation.Cacheable) 由没有范围注释的 @Produces 方法创建的 bean 的默认范围是什么? - What's the default scope for a bean created by a @Produces method without a scope annotation? Spring - @Cacheable 注释不适用于 java 方法 - Spring - @Cacheable annotation not working on java method 使用注入的bean方法的返回值作为@Cacheable批注中的键 - Using Injected bean method return value as key in @Cacheable annotation Spring 缓存 @Cacheable - 从同一 bean 的另一个方法调用时不工作 - Spring Cache @Cacheable - not working while calling from another method of the same bean 为什么Spring会对@Cacheable带注释的方法的单次调用执行两次@Cacheable keyGenerator - Why does Spring execute @Cacheable keyGenerator 2 times for a single invocation of @Cacheable annotated method Spring Boot 中的可缓存注解 - Cacheable Annotation in Spring Boot Spring @Cacheable 和@Async 注解 - Spring @Cacheable and @Async annotation
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM