问题描述
我有一个 SpringBoot + Security + EhCache 项目。有一个围绕 SecurityContextHolder 的包装类(LoggedUserInfo)和一个处理用户信息的服务:
unsafe
我的缓存配置为:
public LoggedUserInfo {
public static String getLogin() {
return SecurityContextHolder.getContext().getAuthentication().getName();
}
}
public UserService {
//(...)
public User getLoggedUser() {
var login = LoggedUserInfo.getLogin();
return getByLogin(login);
}
@Cacheable(value = "userByLogin",key = "#login")
public User getByLogin(String login) {
return userRepository.findByLogin(login);
}
}
UserService::getByLogin 的缓存工作正常。我想对 UserService::getLoggedUser 做同样的事情,但基于当前用户登录。
在阅读了 cache 和 spel 文档后,我发现有可能是这样的:
<cache alias="userByLogin">
<key-type>java.lang.String</key-type>
<value-type>com.myproject.User</value-type>
<expiry>
<ttl unit="hours">24</ttl>
</expiry>
<resources>
<heap unit="MB">1</heap>
</resources>
</cache>
或:
@Cacheable(value = "userByLogin",key = "T(com.myproject.LoggedUserInfo).getLogin()")
public User getLoggedUser() {\\...}
但是,如果我尝试这样做,每次调用 getLoggedUser 时都会出现警告并且从不使用缓存:
@Cacheable(value = "userByLogin",key = "T(com.myproject.LoggedUserInfo).login")
public User getLoggedUser() {\\...}
我错过了什么?
解决方法
您可以尝试提高最大对象图大小(默认值:1000)。
你可以这样调整:
<cache alias="userByLogin">
<key-type>java.lang.String</key-type>
<value-type>com.myproject.User</value-type>
<expiry>
<ttl unit="hours">24</ttl>
</expiry>
<resources>
<heap unit="MB">1</heap>
</resources>
<heap-store-settings>
<max-object-graph-size>10000</max-object-graph-size>
</heap-store-settings>
</cache>
,
阅读this后,我解决了更改缓存配置以限制条目数而不是内存使用量的问题:
<cache alias="userByLogin">
<key-type>java.lang.String</key-type>
<value-type>com.myproject.User</value-type>
<expiry>
<ttl unit="hours">24</ttl>
</expiry>
<resources>
<heap>150</heap>
</resources>
</cache>
我仍然不明白为什么前一个使用 UserService::getByLogin 而不是 UserService::getLoggedUser。