RedisTemplate注入时机问题

我在springboot项目中使用spring cache,这个项目引入了一个common-service jar包,包里有定义

@Configuration  
@ConditionalOnClass(RedisTemplate)  
class RedisConfig {

  @Primary  
  @Bean  
  RedisTemplate<String, Object> redisTemplate() {
     ...
  }

  @Bean  
  StringRedisTemplate stringRedisTemplate() {
     ...
  }
}

可是启动后,报错

Parameter 0 of method cacheManager in org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration required a bean of type 'org.springframework.data.redis.core.RedisTemplate' that could not be found.
  - Bean method 'redisTemplate' in 'RedisAutoConfiguration.RedisConfiguration' not loaded because @ConditionalOnMissingBean (names: redisTemplate; SearchStrategy: all) found bean 'redisTemplate'
  - Bean method 'stringRedisTemplate' in 'RedisAutoConfiguration.RedisConfiguration' not loaded because @ConditionalOnMissingBean (types: org.springframework.data.redis.core.StringRedisTemplate; SearchStrategy: all) found bean 'stringRedisTemplate'
  

这个错我理解不能,说是RedisAutoConfiguration.RedisConfiguration发现有bean 'redisTemplate'和'stringRedisTemplate',所以不加载这俩bean了,既然有这俩bean了,为何又说RedisCacheConfiguration找不到'RedisTemplate'类型的bean?这个报错不是前后矛盾吗?

另外,最根本的,为何我在common-service模块中有RedisConfig类中写了'redisTemplate'和'stringRedisTemplate'两个bean,这俩bean为何不能被RedisAutoConfiguration.RedisConfiguration发现?

111.png

这里说是
@AutoConfigureAfter(RedisAutoConfiguration.class)
@ConditionalOnBean(RedisTemplate.class)
但是打断点跑到这里时,并没有先加载RedisAutoConfiguration.class和RedisConfig ,感觉@AutoConfigureAfte和@ConditionalOnBean都没起作用。

将@EnableCaching去掉后, 将@EnableCaching去掉后,加载RedisAutoConfiguration.class和RedisConfig 是有被加载的

阅读 9.9k
3 个回答

不知道你的 Springboot 版本是多少,但是问题应该出在了你自定义的 Redis 配置类和 Springboot 中自带的配置类发生了冲突。如果你要用自定义的配置,可以试一下使用 @Qualifier 注解,具体方法如下:

第一步:在配置类中为 Bean 指定名称

@Primary  
@Bean(name="myRedisTemplate")
RedisTemplate<String, Object> redisTemplate() {
    ...
}

第二步:注入依赖时使用 @Qualifier 注解

@Autowired
@Qualifier("myRedisTemplate")
private RedisTemplate redisTemplate;

引入的包里配置的bean有生效吗?

image.png
cacheManager(RedisTemplate<Object, Object> redisTemplate)方法需要的泛型为<Object, Object>,而你自己的配置类RedisTemplate泛型为<String, Object>,导致注入不了。所以spring就打算用默认的RedisTemplate来注入,又发现beanName为redisTemplate的对象已经存在了
image.png

推荐问题
宣传栏