返回顶部
首页 > 资讯 > 后端开发 > 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://lsjlt.com/news/160625.html(转载时请注明来源链接)

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

猜你喜欢
  • 解决springCache配置中踩的坑
    目录springCache配置中踩的坑先附上正确的配置springCache配置及一些问题的解决配置@Cacheable参数@CacheEvict 参数@CachePut 参数spr...
    99+
    2024-04-02
  • 如何解决springCache配置中的坑
    本篇内容介绍了“如何解决springCache配置中的坑”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!springCache配置中踩的坑项目...
    99+
    2023-06-22
  • FastJSON字段智能匹配踩坑的解决
    背景 2021年第一天早上,客户突然投诉说系统的一个功能出了问题,紧急排查后发现后端系统确实出了bug,原因为前端传输的JSON报文,后端反序列化成JavaBean后部分字段的值丢失...
    99+
    2024-04-02
  • js正则test匹配的踩坑及解决
    目录引言这样去匹配,有什么问题吗?为什么是 true 、false 、true 怎么解决呢?引言 本瓜相信你一定经常用以下这种最最简单的正则来判断字符串中是否存在某个子字符(别说了,...
    99+
    2024-04-02
  • SpringMVC配置404踩坑记录
    目录前言错误原因总结和教训前言 在学习SpringMVC的路上真是开门就遇见拦路虎了,在配置的时候一直是按照硅谷的视频配置的。但是跑起来就一直是404,这个就很搞人心态了。在配置环境...
    99+
    2024-04-02
  • VSCODE+PHP8.2配置踩坑记录
    VSCODE+PHP8.2配置踩坑记录 – WhiteNight's Site 我配置过的最恶心的环境之一:windows上的php。另一个是我centos服务器上的php。 进不了断点 端口配置和xdebug的安装 这个应该是最...
    99+
    2023-10-21
    服务器 vscode php
  • ResponseBodyAdvice踩坑及解决
    场景 通过ResponseBodyAdvice实现Rest接口的日志统一管理 正文 ResponseBodyAdvice原理自己百度,代码比较少但是我实践的时候发现有几个坑需要注意一...
    99+
    2024-04-02
  • 解决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+
    2024-04-02
  • 解决Pytorch中Batch Normalization layer踩过的坑
    1. 注意momentum的定义 Pytorch中的BN层的动量平滑和常见的动量法计算方式是相反的,默认的momentum=0.1 BN层里的表达式为: 其中γ和β是可以学习的参...
    99+
    2024-04-02
  • 在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的坑
  • vue使用Swiper踩坑解决避坑
    目录我的Swiper定义:报错信息:保留默认名class:swiper-container查看GitHub我的Swiper定义: Failed to execute 'get...
    99+
    2023-05-20
    vue Swiper踩坑解决 vue Swiper避坑
  • SpringMVC配置404踩坑的示例分析
    这篇文章给大家分享的是有关SpringMVC配置404踩坑的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。错误错误就是一直报404,也就说找不到路径。怎么试路径还是404。我相信大家也是非常讨厌404的吧...
    99+
    2023-06-29
  • 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
  • 解决spring集成redisson踩过的坑
    目录spring集成redisson踩过的坑第一坑就是版本兼容问题第二个坑是设置密码问题spring整合redisson配置配置方式单节点配置standalone哨兵配置sentin...
    99+
    2024-04-02
  • springboot整合freemarker的踩坑及解决
    目录springboot整合freemarker踩坑报错问题原因解决方法springboot freemarker基础配置及使用1.基础配置2.基础使用springboot整合fre...
    99+
    2024-04-02
  • 如何解决Go gorm踩过的坑
    这篇文章给大家分享的是有关如何解决Go gorm踩过的坑的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是gogo是golang的简称,golang 是Google开发的一种静态强类型、编译型、并发型,并具有垃...
    99+
    2023-06-14
  • vue3pinia踩坑及解决方案详解
    目录安装用法1、Cannot access 'useUserStore' before initialization重现步骤问题原因解决方案安装 yarn add ...
    99+
    2023-03-06
    vue3 pinia踩坑 vue3 pinia
  • mybatisplus之Wrappers.ne踩坑记录解决
    目录一段看似平平无奇的代码报了异常将classroom是否为null单独拿出来判断一段看似平平无奇的代码 Classroom classroom = this.getOne( W...
    99+
    2023-05-19
    mybatisplus Wrappers.ne踩坑 mybatisplus Wrappers.ne
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作