简体   繁体   English

使用注入的bean方法的返回值作为@Cacheable批注中的键

[英]Using Injected bean method return value as key in @Cacheable annotation

I have an @Cacheable annotated method in one of my beans, and I'd like to use the currently logged in user ID as the key for the Cache. 我的一个bean中有一个带有@Cacheable注释的方法,我想使用当前登录的用户ID作为Cache的键。 However, I'm using Spring Security and have an Injected service as an instance variable in this bean that calls SecurityContextHolder.getContext().getAuthentication() to return the user ID. 但是,我使用的是Spring Security,并且在此bean中有一个Injected服务作为实例变量,该实例调用SecurityContextHolder.getContext()。getAuthentication()返回用户ID。 Hence, I have a zero-argument constructor on the @Cacheable method. 因此,我在@Cacheable方法上有一个零参数的构造函数。 Is there anyway to use the user ID returned from my injected service's method as the key for the Cache? 无论如何,是否可以使用从注入服务的方法返回的用户ID作为Cache的密钥?

@Service
public class MyServiceImpl implements MyService {

@Inject
private UserContextService userContextService;

@Override
@Cacheable("myCache")
public String getInformation() {
  //use this as the key for the cache entry
String userId = userContextService.getCurrentUser();
return "something";
}
}

UserContextService implementation: UserContextService的实现:

@Service
public class UserContextServiceImpl implements UserContextService {

public String getCurrentUser() {
return SecurityContextHolder.getContext().getAuthentication().getName();
}

}

I found this question, but it's somewhat different from what I'd like to do. 我找到了这个问题,但与我想做的有所不同。 I don't think this functionality is possible with a static method. 我认为静态方法无法实现此功能。

Using Spring beans as a key with @Cacheable annotation 使用Spring bean作为具有@Cacheable批注的键

I would write this class so that the userId was an argument to the getInformation() method, and make users of the method/service pass lookup the ID themselves. 我将编写此类,以便将userId作为getInformation()方法的参数,并使该方法/服务的用户自己通过ID进行查找。

@Override
@Cacheable("myCache")
public String getInformation(String userId) { ... }

IMO it's a bad practice to write your service-layer to use the Spring Security context directly, as it limits the usefulness of the service - if you implement some sort of REST API that doesn't use Spring Security (just as an example), then getCurrentUser() might have no meaning / return value. IMO的做法是将服务层直接编写为直接使用Spring Security上下文是一种不好的做法,因为它限制了该服务的实用性-如果您实现某种不使用Spring Security的REST API(仅作为示例),那么getCurrentUser()可能没有任何意义/返回值。 Then MyServiceImpl is unusable if Spring Security is not used for that request, and this method is unusable if you ever need to support something like "admin user needs to look up information for user X". 然后,如果未将Spring Security用于该请求,则MyServiceImpl将不可用,如果您需要支持诸如“管理员用户需要为用户X查找信息”之类的东西,则此方法将不可用。

Let the web-facing layer worry about how to extract the userid from the security context, rather than your service layer. 让面向Web层担心如何从安全上下文而不是服务层提取用户ID。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM