广告
返回顶部
首页 > 资讯 > 后端开发 > Python >解决springCache配置中踩的坑
  • 894
分享到

解决springCache配置中踩的坑

2024-04-02 19:04:59 894人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录springCache配置中踩的坑先附上正确的配置sprinGCache配置及一些问题的解决配置@Cacheable参数@CacheEvict 参数@CachePut 参数spr

springCache配置中踩的坑

项目基于SpringBoot,使用了SpringCache。

早先在网上找了一份SpringCache的配置,后来由于需要使用到自定义序列化方法,注入一个自定义的序列化类。但是在后来发现自定义的序列化类始终没有调用,后来查看源码后终于发现了原因

先附上正确的配置


  @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory, SessionSerializer serializer) {
        logger.debug("生成缓存管理器");
        logger.debug("注入的序列化工具={}", serializer);
        RedisSerializationContext.SerializationPair pair = RedisSerializationContext.SerializationPair.fromSerializer(serializer);
        logger.debug("生成的cache序列化工具={}", pair);
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();  // 生成一个默认配置,通过config对象即可对缓存进行自定义配置
        config = config.entryTtl(Duration.ofMinutes(10))     // 设置缓存的默认过期时间,也是使用Duration设置
                .serializeValuesWith(pair)
//                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .disableCachingNullValues()
        ;     // 不缓存空值
        logger.debug("初始化完成的config={}", config);
        // 设置一个初始化的缓存空间set集合
        Set<String> cacheNames = new HashSet<>();
        cacheNames.add(CACHE_NAME);
        return RedisCacheManager.builder(new CusTtlRedisCacheWriter(factory))     // 使用自定义的缓存配置初始化一个cacheManager
                .cacheDefaults(config)//这一句必须要最先执行,否则实际运行时使用的是defaultConfig
                .initialCacheNames(cacheNames)
//                .withInitialCacheConfigurations(configMap)
//                .transactionAware()
                .build();
    }

重要在于最后一行return的时候,早先的找到的资料说initialCacheNames方法一定要先执行,否则就会巴拉巴拉~~~,,结果就掉坑了

如果initialCacheNames方法先执行的话,实际上CacheManager里使用的是DefaultConfig,里面的序列化方式也就是jdk序列化,后面在调用cacheDefaults也没有用了。

所有,cacheDetaults方法一定要先执行

springCache配置及一些问题的解决

配置

1. applicationContext.xml


<beans xmlns="Http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:cache="http://www.springframework.org/schema/cache"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
  
    <cache:annotation-driven />
  <!-- 定义缓存管理 -->
    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
        <property name="caches">
            <set>
                <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
                      p:name="default"/>
                <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
                      p:name="activityCache"/>
                <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
                      p:name="awardsCache"/>
            </set>
        </property>
    </bean>

Spring内部默认使用 ConcurrentHashMap 来存储, 配置中的 activityCache awardsCache 就是一个一个的 ConcurrentHashMap 对象的名字. 另外 spring还支持使用 EHCache 来存储缓存.

2. 在service的实现类上加上 @Cacheable


//@Service
//public class LotteryActivityServiceImpl implements LotteryActivityService
@Cacheable(value = "activityCache", key = "#shortName")
public LotteryActivity findByShortName(String shortName) {
    log.info("query activity : {} from database.", shortName);
    return activityRepository.findByShortName(shortName);
}

@Cacheable参数

value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:@Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如: @Cacheable(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 例如: @Cacheable(value=”testcache”,condition=”#userName.length()>2”)

在需要清除缓存的方法上加上@CacheEvict


@CacheEvict(value="activityCache", allEntries = true, beforeInvocation = true)
public void cleanActivityCache(String shortName) {
    log.info("cleaned cache activity : {}", shortName);
}

@CacheEvict 参数

value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如: @CachEvict(value=”mycache”) 或者 @CachEvict(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如: @CachEvict(value=”testcache”,key=”#userName”
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 例如: @CachEvict(value=”testcache”, condition=”#userName.length()>2”)
allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 例如: @CachEvict(value=”testcache”,allEntries=true)
beforeInvocation 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 例如: @CachEvict(value=”testcache”,beforeInvocation=true)

当需要保证方法被调用,又希望结果被缓存, 可以使用@CachePut


@CachePut(value="accountCache",key="#account.getName()")// 更新 accountCache 缓存
 public Account updateAccount(Account account) { 
   return updateDB(account); 
 } 

@CachePut 参数

value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如: @Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如: @Cacheable(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 例如: @Cacheable(value=”testcache”,condition=”#userName.length()>2”)

注解最好加在实现类而不是接口的方法上

Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Cache* annotation, as opposed to annotating interfaces. You certainly can place the @Cache* annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"), then the caching settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a caching proxy, which would be decidedly bad.

带有@Cache* 注解的方法不能被定义在调用该方法的类里, 比如 UserController要调用 findUserByName(String name), 且该方法有 @Cacheabele注解, 那么该方法就不能被定义在 UserController中

In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual caching at runtime even if the invoked method is marked with @Cacheable - considering using the aspectj mode in this case.

@Cache*注解要加在 public 方法上

When using proxies, you should apply the @Cache* annotations only to methods with public visibility. If you do annotate protected, private or package-visible methods with these annotations, no error is raised, but the annotated method does not exhibit the configured caching settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods as it changes the bytecode itself.

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: 解决springCache配置中踩的坑

本文链接: https://www.lsjlt.com/news/160625.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 解决springCache配置中踩的坑
    目录springCache配置中踩的坑先附上正确的配置springCache配置及一些问题的解决配置@Cacheable参数@CacheEvict 参数@CachePut 参数spr...
    99+
    2022-11-12
  • 如何解决springCache配置中的坑
    本篇内容介绍了“如何解决springCache配置中的坑”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!springCache配置中踩的坑项目...
    99+
    2023-06-22
  • FastJSON字段智能匹配踩坑的解决
    背景 2021年第一天早上,客户突然投诉说系统的一个功能出了问题,紧急排查后发现后端系统确实出了bug,原因为前端传输的JSON报文,后端反序列化成JavaBean后部分字段的值丢失...
    99+
    2022-11-12
  • js正则test匹配的踩坑及解决
    目录引言这样去匹配,有什么问题吗?为什么是 true 、false 、true 怎么解决呢?引言 本瓜相信你一定经常用以下这种最最简单的正则来判断字符串中是否存在某个子字符(别说了,...
    99+
    2022-11-13
  • 解决Go gorm踩过的坑
    使用gorm.Model后无法查询数据 Scan error on column index 1, name “created_at” 提示: Scan error on...
    99+
    2022-06-07
    gorm GO
  • SpringBootTest--踩坑错误的解决
    目录SpringBootTest 踩坑SpringBootTest的一个小坑注意点1、我当时运行SpringBoot测试类的时候踩这个坑2、解决方法SpringBootTest 踩坑...
    99+
    2022-11-12
  • SpringMVC配置404踩坑的示例分析
    这篇文章给大家分享的是有关SpringMVC配置404踩坑的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。错误错误就是一直报404,也就说找不到路径。怎么试路径还是404。我相信大家也是非常讨厌404的吧...
    99+
    2023-06-29
  • 在uni-app中踩过的坑及解决
    目录1. props传值变量名不要使用id2.组件没有页面事件3.关于背景图片4.代理5.z-index的问题6.trim去除前后空格失效总结1. props传值变量名不要使用id ...
    99+
    2023-05-16
    uni-app踩过的坑 uni-app踩坑 uni-app的坑
  • 解决Pytorch中Batch Normalization layer踩过的坑
    1. 注意momentum的定义 Pytorch中的BN层的动量平滑和常见的动量法计算方式是相反的,默认的momentum=0.1 BN层里的表达式为: 其中γ和β是可以学习的参...
    99+
    2022-11-12
  • react中使用usestate踩坑及解决
    目录usestate的常规用法useState遇到的坑1、useState不适合复杂对象的更改2、useState异步回调的问题3、根据hook的规则,使用useState的位置有限...
    99+
    2022-11-13
    react使用usestate usestate踩坑 react中usestate
  • 详解JavaScheduledThreadPoolExecutor的踩坑与解决方法
    目录概述还原"大坑"解决方案更推荐的做法原理探究总结概述 最近项目上反馈某个重要的定时任务突然不执行了,很头疼,开发环境和测试环境都没有出现过这个问题。定时任务采...
    99+
    2022-11-13
    Java ScheduledThreadPoolExecutor
  • springboot整合freemarker的踩坑及解决
    目录springboot整合freemarker踩坑报错问题原因解决方法springboot freemarker基础配置及使用1.基础配置2.基础使用springboot整合fre...
    99+
    2022-11-13
  • 解决spring集成redisson踩过的坑
    目录spring集成redisson踩过的坑第一坑就是版本兼容问题第二个坑是设置密码问题spring整合redisson配置配置方式单节点配置standalone哨兵配置sentin...
    99+
    2022-11-12
  • 如何解决Go gorm踩过的坑
    这篇文章给大家分享的是有关如何解决Go gorm踩过的坑的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是gogo是golang的简称,golang 是Google开发的一种静态强类型、编译型、并发型,并具有垃...
    99+
    2023-06-14
  • 导入SpringCloud依赖踩的坑及解决
    目录导入SpringCloud依赖踩坑上网找解决方案 springCloud依赖导入失败总结导入SpringCloud依赖踩坑 在使用SpringCloud的时候需要导入...
    99+
    2023-05-15
    导入SpringCloud依赖 SpringCloud依赖 SpringCloud依赖踩坑
  • springboot2.x引入feign踩的坑及解决
    目录springboot2.x引入feign踩的坑一、需求二、什么是feign三、springboot1.x中feign的使用四、springboot2.x中feign的使用feig...
    99+
    2022-11-13
  • TypeScript踩坑之TS7053的问题及解决
    目录TypeScript踩坑之TS7053解决方法总结TypeScript踩坑之TS7053 错误:TS7053: Element implicitly has an ‘...
    99+
    2023-01-28
    TypeScript踩坑 TypeScript踩坑TS7053 TypeScript TS7053
  • 解决spring boot2集成activiti6踩过的坑
    spring boot2集成activiti6踩过的坑 1.activiti中的mybaitis版本冲突 错误信息 Caused by: java.lang.NoSuchField...
    99+
    2022-11-12
  • ShardingJdbc读写分离的BUG踩坑解决
    目录前言数据库介绍1. 常规写完读2. 在一个 service 里面调用另一个 service3. 新开一个线程去调用 service24. service2 新开一个事务执行前言 ...
    99+
    2022-11-13
  • mybatis配置mapper-locations的坑及解决
    目录mybatis配置mapper-locations的坑mapperLocations配置失效问题根源解决mybatis配置mapper-locations的坑 很多时候想把xml...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作