关于spring echache无法正常缓存的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于spring echache无法正常缓存的问题相关的知识,希望对你有一定的参考价值。

相关配置及代码:
ehcache.xml:<?xml version="1.0" encoding="UTF-8"?><ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.sf.net/ehcache.xsd" updateCheck="true" monitoring="autodetect"> <diskStore path="c:/SYS_app/Cache" /> <cache name="Region_Cache" maxElementsInMemory="2" maxElementsOnDisk="1" eternal="false" overflowToDisk="true" diskSpoolBufferSizeMB="20" timeToIdleSeconds="36000" timeToLiveSeconds="72000" memoryStoreEvictionPolicy="LFU" /></ehcache>applicationContext.xml:<!-- Begin to Cache for speed up! --> <cache:annotation-driven cache-manager="cacheManager"/> <!-- cacheManagerFactory --> <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:ehcache.xml"/> <!-- cacheManager --> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="cacheManagerFactory"/>
RegionService.java:@Service("regionService")public class RegionService extends BaseService
@Autowired public RegionRepository regionRepository;
//需要参数条件作为key进行缓存,只缓存符合条件的 @Cacheable(value = "Region_Cache", key = "'REGION_'+#parentCode") public List<RegionBean> getChildrenByPcode(String parentCode) return regionRepository.getChildrenByPcode(parentCode);
@Cacheable(value = "Region_Cache", key = "'REGION_86'") public List<RegionBean> printCache() return null;

参考技术A 你测试方法有问题,在测试类里面new出ClassPathXmlApplicationContext,但是你下面用来从数据库取数据在同一个ClassPathXmlApplicationContext下只有一次,怎么可能会有缓存呢?,等于是每次都是new的不同的ClassPathXmlApplicationContext,每次都是new的不同的cache对象,你需要在测试中连续取几次数据。这样就可以看到结果追问

我那个是单元测试,而且出来的缓存效果我也看到了啊,单元测试中我调了四次,前两次都是需要执行SQL的,但是从运行结果看,确实执行了一次,这就是缓存的效果,后两次我执行返回的缓存中数据的大小,都如期返回正确。

Spring Security - 无法避免缓存控制

【中文标题】Spring Security - 无法避免缓存控制【英文标题】:Spring Security - No way to avoid cache-control 【发布时间】:2015-10-03 11:04:50 【问题描述】:

我有一个应用程序并使用 spring 的控制器映射将图像加载给我的用户。 (输入流、响应等)。

在我的控制器中,我将标头设置为缓存控制、基于文件等。但是在所有请求中总是有 pragma: no-cache 和 Cache-Control:"max-age=0" ,这替换了我的响应设置.

我想尽一切办法解决这个问题,但没有任何效果。

我已经阅读了所有页面并尝试了我发现的所有内容: http://docs.spring.io/autorepo/docs/spring-security/3.2.0.CI-SNAPSHOT/reference/html/headers.html

我的 spring security.xml 有:

    <security:headers disabled="true"/>

谁有解决这个问题的好主意?

请记住,要加载我需要通过控制器加载的图像,我从不直接调用 static。

【问题讨论】:

您能否提供用于在控制器中设置标题的代码?如果完全删除 Spring Security,问题是否仍然存在? 【参考方案1】:

根据您链接到的Spring Security reference (3.2.0),

使用没有子元素的元素可以轻松添加所有默认标题

单独添加headers 将打开所有子元素(例如缓存控制、xxs、...)。要么根本不包含标题,要么明确指定要启用的子元素。

顺便说一句,我不认为disabled 是标题的属性(对于 3.2.0)。如果您使用的是version 4.0,则有一个disabled 属性以及disabled-defaults,这可能是您想要的。

【讨论】:

现在试过了,没有解决。我想删除我的请求的“无缓存”,不包括它们。 你尝试了什么?你能展示一下你更新后的配置是什么样子的吗? 当然,现在的配置是: 对于安全版本会开启所有默认的headers(包括缓存控制)。如果您不需要任何标头,只需删除 。如果您需要一些标题,请明确列出它们。如果您的安全版本是 4.0,请尝试添加属性 disabled-defaults="true" 我也试过了,把所有东西都拿出来,还是一样。我不需要任何东西,但它在我的应用程序中保持无缓存。【参考方案2】:

已经有一段时间了 - 但是在研究同样的问题时,我发现了这篇文章,这对我来说很有效 -

disable caching for specific url in spring security

上面提到的解决方案的美妙之处在于它允许每个标头专门使用其原始类,并使用 antmatchers 将特定的请求路径与相应的标头对齐。在我的例子中,我为我的静态资源使用了一个单独的缓存引用,并设置了缓存到期,另一个用于所有没有缓存的 jsps。由于它是一个蚂蚁匹配器,控制器 uri 可以使用相同的方法进行匹配。

【讨论】:

【参考方案3】:

如果使用基于 Java 的配置,可以通过这种方式禁用缓存控制标头:

@Configuration
@EnableWebMvcSecurity
class SpringWebSecurityConfig extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(final HttpSecurity http) throws Exception 
        http.headers().cacheControl().disable();
    

这将删除 CacheControlHeadersWriter 并且 Spring 将不再写入缓存控制标头。

【讨论】:

我在哪里放置这个配置? 感谢您的回答。为我工作。 禁用默认的 Spring 安全行为是个坏主意。你在这里阅读更多:baeldung.com/spring-security-cache-control-headers【参考方案4】:

Cache-Control 标头可以通过在 HttpServletResponse 中覆盖它们来基于每个操作进行控制:

@RequestMapping(value = "/foo", method = RequestMethod.GET)
public String someAction(HttpServletResponse response) 
    response.setHeader("Cache-Control", "no-transform, public, max-age=86400");

    // ...

无需摆弄 Spring Security 配置。

见http://docs.spring.io/spring-security/site/docs/current/reference/html/headers.html#headers-cache-control。

【讨论】:

这是我发现的唯一可行的方法。非常感谢! 非常感谢。您的解决方案节省了大量时间。 这将复制标题而不是覆盖它。我收到no-cache, no-store, max-age=0, must-revalidate, max-age=7200 @Kumait 适用于 Spring 5.1.9【参考方案5】:

添加到aha 的答案。您还需要用一些垃圾覆盖 Pragma 标头。

@RequestMapping(value = "/foo", method = RequestMethod.GET)
public String someAction(HttpServletResponse response) 
    response.setHeader("Cache-Control", "no-transform, public, max-age=86400");
    response.setHeader("Pragma", "");
    // ...

Expires 标头仍然显示在响应中,但在大多数浏览器中似乎被 Cache-Control 标头覆盖。

【讨论】:

【参考方案6】:

下面的代码应该在 spring 5.X 中为你工作

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.headers()
        .defaultsDisabled()
        .cacheControl();
    

【讨论】:

以上是关于关于spring echache无法正常缓存的问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 Hibernate + Spring 进行缓存 - 一些问题

关于Redis Desktop Manager无法连接Ubuntu上的redis容器

解决卡顿 投屏以及缓存问题的方法

关于AOP无法切入同类调用方法的问题

Spring Security - 无法避免缓存控制

Java / Spring:无法在单元测试中测试缓存