当前位置: 首页 > news >正文

项目中同时使用Redis(lettuce)和Redisson的报错

温馨提示:图片有点小,可以放大页面进行查看...

问题1:版本冲突

直接上图,这个错表示依赖版本不匹配问题,我本地SpringBoot用的是2.7,但是Redisson版本用的3.32.5。

 我们通过点击 artifactId跟进去

发现它依赖的SpringBoot版本是3.1

 换成3.18.0之后就好了


 大家碰到NotClassDefFoundError ,就优先考虑依赖版本问题,连类定义都没有,太离谱了...

 问题2:循环依赖

这个错误还是很容易就复现出来的...

 这里放大关键报错信息

我在RedisConfig中同时完成RedisTemplate和RedissonClient的初始化。

因为我通过字段注入RedissonConnectionFactory。

当其他类需要redisTemplate的时候,即依赖RedisConfig,去完成Bean注册的时候发现redisTemplate依赖RedissonConnectionFactory,而RedissonConnectionFactory依赖RedissonClient,而RedissonClient依赖RedisConfig。走了一圈,发现RedisConfig依赖RedisConfig,所以产生了循环依赖。

@Configuration
public class RedisConfig {

    @Autowired
    private RedissonConnectionFactory fa;

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private Integer port;

    @Value("${spring.redis.password}")
    private String password;

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedissonConnectionFactory factory) {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.setDefaultSerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        // redis为单机模式
        config.useSingleServer()
                .setAddress("redis://" + host + ":" + port);
        return Redisson.create(config);
    }
}

眼尖的朋友可能会有疑问,我为什么要将RedissonConnectionFactory作为字段,依赖注入?

其实原代码用的是RedisConnectionFactory,同时redisTemplate用的RedisConnectionFactory完成的Bean初始化。我在它的基础上加了个RedissonClient的初始化。

@Configuration
public class RedisConfig {

    @Autowired
    private RedisConnectionFactory factory;

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.setDefaultSerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }
}

但其实,我这里不管用RedissonConnectionFactory还是RedisConnectionFactory都是一样的,最终其实用的都是 RedissonConnectionFactory....

先说答案:因为项目中引入了Redisson框架,因此Spring容器会优先使用RedissonConnectionFactory,因为会优先执行 RedissonAutoConfiguration 文件。

下面是分析过程:

我将字段注入去掉,并且方法参数改成了RedissonConnectionFactory,进行debug

 跟进RedissonConnectionFactory,继续跟进getConnection方法

 发现这里已经变成了redissonConnection

因为:项目中使用了Redisson,优先初始化RedissonClient,【依赖于RedissonConnectionFactory,所以RedissonConnectionFactory也初始化了】


看一下为什么RedisConnectionFactory会被替换为RedissonConnectionFactory:

 跟进RedisConnectionFactory,它继承自PersistenceExceptionTranslator

 查看PersistenceExceptionTranslator的引用,发现同时有RedisConnectionFactory和RedissonConnectionFactory两个Bean

 这里使用的是RedissonConnectionFactory。


解决办法:

方法1:将字段注入去掉,这样的话可以打破依赖关系:
RedisConfig - > RedissonConnectionFactroy 

方法2:在启动类上,添加属性 exclude ,将RedisAutoConfiguration 排除掉,这样的话,也是打破了RedisConfig -> RedissonConnectionFactory,改成了依赖RedisConnectionFactory

http://www.dtcms.com/a/55049.html

相关文章:

  • 服务器带宽堵塞会对网站访问产生哪些影响?
  • 打破界限!家电行业3D数字化营销,线上线下无缝对接
  • Yashan DB 体系结构
  • 初识云计算
  • 【FastAPI】 AI场景快速学习指南
  • JS采集数据爬虫-Fetch API 和 XMLHttpRequest 有什么区别?
  • 影刀 RPA 实战开发阶段总结
  • Linux--如何安装rockyLinux9虚拟机
  • 3D匹配算法简述
  • OpenCV计算摄影学(19)非真实感渲染(Non-Photorealistic Rendering, NPR)
  • Vue入门常见指令
  • 【通义万相】蓝耘智算 | 开源视频生成新纪元:通义万相2.1模型部署与测评
  • 通过CycleGAN把不成对的可见光数据转换为红外数据
  • Debian系统grub新增启动项
  • 【Leetcode 每日一题 - 补卡】2588. 统计美丽子数组数目
  • XPath 定位复杂元素的最佳实践
  • 查看k8s集群的资源使用情况
  • Python机器学习小项目实战:随机森林模型优化,提升信用卡欺诈检测效能
  • 大白话如何使用 CSS 实现响应式布局?请列举一些常见的方法。
  • 8. 机器人模型训练与评估(具身智能机器人套件)
  • React基础之受控表单绑定
  • ReferenceError: assignment to undeclared variable xxx
  • Python 编程题 第七节:没出现过的数字、替换空格、快乐数、立方根、最长公共前缀
  • 深度解读,消防设施操作员考试重难点突破
  • node.js内置模块之---crypto 模块
  • redis缓存的应用
  • MySQL很久没碰,复习一下
  • 【从零开始学习计算机科学】数字逻辑(一)绪论
  • 从多智能体变成一个具有通过场景生成多个决策路径 并在实施的过程中优化决策路径 openmanus 致敬开源精神中的每一个孤勇者
  • 电子档案图片jpg格式表单化审核