【问题标题】:Spring @Cacheable with filter带有过滤器的 Spring @Cacheable
【发布时间】:2015-05-27 20:37:32
【问题描述】:

每个实体类都有 user.id 值,我在所有服务上都有过滤器,这些过滤器在数据库级别按 principal.id 和实体 user.id 过滤数据,只需添加 where 子句。我开始使用@Cacheable 弹簧选项。但过滤器不适用于 spring-cache。如何从缓存中过滤数据?

@Override
@Cacheable(value = "countries")
public List<Country> getAll() {
    return countryDao.findAll();
}

如果值在缓存中,则不同用户可以访问其他用户的值。

【问题讨论】:

    标签: spring spring-mvc spring-security ehcache spring-cache


    【解决方案1】:

    来自文档 “顾名思义,@Cacheable 用于划分可缓存的方法 - 即,将结果存储到缓存中的方法,因此在后续调用(使用相同的参数)时,缓存中的值无需返回实际执行该方法。”

    在您的情况下,您没有参数,因此每次调用 getAll 时都会返回缓存的版本。

    如果您的 countryDao.findAll() 在数据库级别注入用户 ID,您会遇到问题,因为第一个调用 countryDao.findAll() 的用户将导致他的结果被缓存,因此其他用户将获得与第一个相同的结果用户。

    一般来说,如果我了解您是如何设计服务的,您通常不会在 db 级别注入用户,而是在服务级别传递它,以便与当前会话(例如 Web 请求)分离)。

    但是,如果您想保持这种状态,它仍然可以这样做:

    @Cacheable(value = "countries", key="#user.id")
    public List<Country> getAll(User user) {     
        return countryDao.findAll();
    }
    

    您所要做的就是将用户传递给该方法,即使您没有显式使用它(但缓存会)。

    【讨论】:

    • 我通过自定义实现密钥生成器和附加参数 - 记录用户 id 解决了这个问题,但由于缓存数据的延迟加载问题,最后我使用 ehcache 作为休眠二级缓存。无论如何谢谢:)
    猜你喜欢
    • 2015-09-22
    • 2020-09-21
    • 1970-01-01
    • 2018-05-25
    • 2017-07-06
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    相关资源
    最近更新 更多