Springboot的redisTemplate究竟用的是哪个bean

文章讨论了在Spring中如何自动装配RedisTemplate对象,特别是在没有自定义bean时,通过@Autowired、@Qualifier和泛型来确定使用的是哪个默认或自定义的RedisTemplate。强调了使用Qualifier注解的重要性以避免歧义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在自动装配一个RedisTemplate对象时,我时常有疑惑用到的究竟是spring自带的还是我们自定义的。

不定义自定义bean时
@Autowired
private RedisTemplate redisTemplate;

上面的redisTemplate实际上是RedisAutoConfiguration类中通过redisTempate这个bean自动装载的。

@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
	RedisTemplate<Object, Object> template = new RedisTemplate<>();
	template.setConnectionFactory(redisConnectionFactory);
	return template;
}

@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
	StringRedisTemplate template = new StringRedisTemplate();
	template.setConnectionFactory(redisConnectionFactory);
	return template;
}

由于该类中还定义了stringRedisTemplate的bean,所以下面的自动装配得到的就是该bean

@Autowired
private RedisTemplate stringRedisTemplate;

注意:句柄必须是stringRedisTemplate,这个句柄对应的是bean的名字。

但是只是通过句柄来确定用的是哪个bean,未免有点不太严谨,因为在我有限的认知中,句柄只是句柄而已,改成其他字符串它还是一个句柄。但是你会发现改了句柄之后就会报错了。

有两种方式可以解决:

1,使用@Qualifier注解

2,将RedisTemplate泛型定义完整,此时句柄可以随便修改

@Autowired
private RedisTemplate<String, String> whichRedisTemplate;

可以得出结论:究竟用的是哪个bean,可以由下面3步来确定

1,@Qualifer注解中标明的bean名字

2,定义的泛型

3,句柄名字

注意:上面3步是由优先顺序的。

如果有好奇下面的定义是用的哪个bean的,可以直接给出答案,是RedisAutoConfiguration类中的redisTempate。

@Autowired
private RedisTemplate<Object,Object> stringRedisTemplate;

有定义自定义bean时

首先我们是不能定义相同的bean名字的。因为已经有了RedisAutoConfiguration类中定义的两个bean,也就是说我们不能再定义名称为redisTemplate或stringRedisTemplate的bean,不然会抛出BeanDefinitionOverrideException

有自定义bean时确定用到的时哪个bean的方法还是前面3步。值得注意的是第2和第3步的定义是可能会产生歧义的。现在自定义下面的bean,注意bean名字和valueSerializer和spring定义的stringRedisTemplate是不一样的

@Bean
public RedisTemplate<String, String> stringRedisTemplate_1(LettuceConnectionFactory connectionFactory) {
    RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Map.class));
    redisTemplate.setConnectionFactory(connectionFactory);
    return redisTemplate;
}

那么下面的定义是用的哪个对象呢

@Autowired
private RedisTemplate<String,String> stringRedisTemplate;

答案是spring自定的stringRedisTemplate,那么如果将上面的句柄改成stringRedisTemplate_2,结果就是会报错,因为spring无法确定,所以会抛出NoUniqueBeanDefinitionException。

也就是说想要确定我们定义的自动装载对象就是我们想要的对象时,最好是泛型和句柄都和定义bean时保持一致。

以上都是废话,总结一句话:实际使用中,最好使用@Qualifier注解。

Spring Boot RedisTemplate 配置可以通过以下步骤完成: 1. 添加 Redis 依赖 在 pom.xml 文件中添加 Redis 依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 2. 配置 Redis 连接信息 在 application.properties 文件中添加 Redis 连接信息: ``` spring.redis.host=127...1 spring.redis.port=6379 spring.redis.password= ``` 3. 配置 RedisTemplateSpring Boot 应用程序中,可以使用 RedisTemplate 来操作 Redis 数据库。可以通过以下方式配置 RedisTemplate: ``` @Configuration public class RedisConfig { @Bean public RedisConnectionFactory redisConnectionFactory() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(); config.setHostName("127...1"); config.setPort(6379); return new LettuceConnectionFactory(config); } @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory()); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } } ``` 在上面的代码中,我们创建了一个 RedisConnectionFactory,它使用 Lettuce 连接 Redis 数据库。然后,我们创建了一个 RedisTemplate,它使用上面创建的 RedisConnectionFactory。我们还设置了 RedisTemplate 的 keySerializer 和 valueSerializer,它们分别用于序列化 Redis 中的键和值。 4. 使用 RedisTemplate 现在,我们已经成功配置了 RedisTemplate,可以在 Spring Boot 应用程序中使用它来操作 Redis 数据库。例如,我们可以使用以下代码将一个对象保存到 Redis 中: ``` @Autowired private RedisTemplate<String, Object> redisTemplate; public void saveObject(String key, Object value) { redisTemplate.opsForValue().set(key, value); } ``` 在上面的代码中,我们使用 RedisTemplate 的 opsForValue() 方法获取 ValueOperations 对象,然后使用 set() 方法将一个对象保存到 Redis 中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值