引言
今天在构建项目的时候引入redisUtils的时候发生了错误,错误如下
***************************
APPLICATION FAILED TO START
***************************
Description:
Field redisTemplateDB0 in net.cc.ucare.adsbhandler.config.RedisConfiguration required a single bean, but 2 were found:
- redisTemplate: defined by method 'redisTemplate' in class path resource [net/cc/ucare/adsbhandler/config/RedisTemplateConfiguration.class]
- stringRedisTemplate: defined by method 'stringRedisTemplate' in class path resource [net/cc/ucare/adsbhandler/config/RedisTemplateConfiguration.class]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
大体意思是,你的这个对象在构建的时候应该是一个,但是却取到了两个,需要将这两个做标志一区分开,可以用@Primary或者@Qualifier注解进行区分.
我的代码如下,这是一个redis的配置类
@Configuration
public class RedisConfiguration {
/**
* redis 0号库
*/
@Autowired
// 这里是上面报错所说的DB0,通过看源码才知道这用的底层都是一样的,怪不得区分不开.
private RedisTemplate redisTemplateDB0;
@Autowired
private StringRedisTemplate stringRedisTemplateDB0;
/**
* redis 1号库
*/
@Autowired
private RedisTemplate redisTemplateDB1;
@Autowired
private StringRedisTemplate stringRedisTemplateDB1;
/**
* redis 2号库
*/
@Autowired
private RedisTemplate redisTemplateDB2;
@Autowired
private StringRedisTemplate stringRedisTemplateDB2;
/**
* redis 3号库
*/
@Autowired
private RedisTemplate redisTemplateDB3;
@Autowired
private StringRedisTemplate stringRedisTemplateDB3;
/**
* redis 6号库
*/
@Autowired
private StringRedisTemplate stringRedisTemplateDB6;
/**
* redis 7号库
*/
@Autowired
private StringRedisTemplate stringRedisTemplateDB7;
@Bean
public RedisUtils redisUtils() {
RedisUtils redisUtils = new RedisUtils();
redisUtils.putRedisTemplate(RedisUtils.db0, null);
redisUtils.putRedisTemplate(RedisUtils.db1, null);
redisUtils.putRedisTemplate(RedisUtils.db2, null);
redisUtils.putRedisTemplate(RedisUtils.db3, null);
redisUtils.putRedisTemplate(RedisUtils.db6, null);
redisUtils.putRedisTemplate(RedisUtils.db7, null);
redisUtils.putStringRedisTemplate(RedisUtils.db0, stringRedisTemplateDB0);
redisUtils.putStringRedisTemplate(RedisUtils.db1, stringRedisTemplateDB1);
redisUtils.putStringRedisTemplate(RedisUtils.db2, stringRedisTemplateDB2);
redisUtils.putStringRedisTemplate(RedisUtils.db3, stringRedisTemplateDB3);
redisUtils.putStringRedisTemplate(RedisUtils.db6, stringRedisTemplateDB6);
redisUtils.putStringRedisTemplate(RedisUtils.db7, stringRedisTemplateDB7);
return redisUtils;
}
}
解决
这里是上面报错所说的DB0,通过看源码才知道这用的底层都是一样的,怪不得区分不开.
这个是报错里的那个类的源码,然后他说加上的那两个注解就需要加在这里
@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
重写后
加上@Override和@Primary注解,因为是Spring配置类,为了让其读到要加上@Configuration注解
加@Qualifier也可以,上网搜一下怎样用就行,需要将名字输入即可
@Configuration
public class RedisTemplateConfiguration extends RedisAutoConfiguration {
@Override
@Bean
@Primary
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
重新运行应该就能成功了
@Bean和@Autowired的区别
@Bean告诉Spring: 这是我修饰的一个实例,请帮我保存着,我会随时过来拿
@Autowried告诉Spring: 麻烦给我我修饰的实例,就像刚才@Bean在你这创建的那种
@Autowried相当于隐藏了getset方法
@Bean相当于一个写好的构造方法,而@Autowired相当于get方法,哈哈