使用基于用户登录的缓存键

问题描述

我有一个 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 做同样的事情,但基于当前用户登录

在阅读了 cachespel 文档后,我发现有可能是这样的:

<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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...