RedisConfig配置注入不进项目中 |
您所在的位置:网站首页 › service注入不进去 › RedisConfig配置注入不进项目中 |
image.png
@Configuration
public class RedisConfig {
@Bean
public CachingConfigurerSupport keyGenerator() {
return new MyCachingConfigurerSupport();
}
public class MyCachingConfigurerSupport extends CachingConfigurerSupport {
@Override
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
}
//缓存管理器
@SuppressWarnings("rawtypes")
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
//设置缓存过期时间
rcm.setDefaultExpiration(300);//秒
return rcm;
}
/**
* 存入对象tostring后的信息
*/
@Bean
public RedisTemplate redisTemplate() {
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(jedisConnectionFactory());
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的key也采用String的序列化方式,需要配置一下StringSerializer,不然key会乱码 /XX/XX
template.setHashKeySerializer(stringRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
// /**
// * 存入对象序列化信息
// *
// * @return
// */
// @Bean
// public RedisTemplate redisSerizlizerObj1() {
// RedisTemplate redisTemplate = new RedisTemplate();
// redisTemplate.setConnectionFactory(jedisConnectionFactory());
// // key采用String的序列化方式
// redisTemplate.setKeySerializer(new StringRedisSerializer());
// // value序列化方式采用jackson
// redisTemplate.setValueSerializer(new RedisObjectSerializer());
//
// // hash的key也采用String的序列化方式
// redisTemplate.setHashKeySerializer(new StringRedisSerializer());
// // hash的value序列化方式采用jackson
// redisTemplate.setHashValueSerializer(new RedisObjectSerializer());
// return redisTemplate;
// }
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
jedisConnectionFactory.setPassword("jihy");
return jedisConnectionFactory;
}
}
@Configuration注解未生效,@Bean无法注入。 这个配置类和别的配置类没有任何区别,@Configuration和@Bean注解都有,无论怎么启动就是注入不进项目中,后来试着将该配置类先移动到其他(可以注入其他配置类的)包中,启动服务发现可以被扫描到。然后再将该配置类拖回原来的包中再重新启动服务,发现也可以了。没想明白为什么,这里记录一下。 看这个方法修改了RedisTemplate的默认序列化方式,默认序列化方式是JdkSerializationRedisSerializer,这里改成Jackson2JsonRedisSerializer序列化方式,可以序列化object对象为json字符串。 /** * 存入对象tostring后的信息 */ @Bean public RedisTemplate redisTemplate() { RedisTemplate template = new RedisTemplate(); template.setConnectionFactory(jedisConnectionFactory()); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // key采用String的序列化方式 template.setKeySerializer(stringRedisSerializer); // value序列化方式采用jackson template.setValueSerializer(jackson2JsonRedisSerializer); // hash的key也采用String的序列化方式,需要配置一下StringSerializer,不然key会乱码 /XX/XX template.setHashKeySerializer(stringRedisSerializer); // hash的value序列化方式采用jackson template.setHashValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; }修改完序列化方式之后,control中还需要使用该类RedisTemplate,通过@Autowired private RedisTemplate template;注入,启动项目报错了。 image.png 报错信息如下: image.pngConsider 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 意思是两个bean不知道注入哪一个,需要给其中一个更高的优先级。那为什么会出现这种情况呢? 首先需要了解Spring装配bean组件的三种方式: 隐式的Bean发现机制和自动装配 在Java中进行装配 在XML中进行装配 值得一提的是,我们在项目中应该优先实用隐式的Bean发现机制和自动装配,其次使用在Java中进行装配,最后再使用在XML中进行装配。 对于本项目使用了 @Configuration+@Bean的基于Java的Bean装配 RedisTemplate类, 然后在control类中又通过@Autowired 隐式的Bean发现机制和自动装配 RedisTemplate类 两种方式导致框架不知道使用哪一个 所以有两种解决方法: 使用@Primary注解(该注解不能修饰属性)正确的 image.png错误的 image.png 配置类中注入的该类的方法名作为属性名 该方法名为 redisTemplate(),RedisTemplate类在项目中的 组件ID 与该方法名同名,在control中 private RedisTemplate redisTemplate; 也使用改名作为属性,经过测试也是可以的。 测试方法是:System.out.println(redisTemplate.getValueSerializer()); 查看打印出来的序列化方式是什么,默认序列化方式是JdkSerializationRedisSerializer @Bean public RedisTemplate redisTemplate() { RedisTemplate template = new RedisTemplate(); template.setConnectionFactory(jedisConnectionFactory()); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // key采用String的序列化方式 template.setKeySerializer(stringRedisSerializer); // value序列化方式采用jackson template.setValueSerializer(jackson2JsonRedisSerializer); // hash的key也采用String的序列化方式,需要配置一下StringSerializer,不然key会乱码 /XX/XX template.setHashKeySerializer(stringRedisSerializer); // hash的value序列化方式采用jackson template.setHashValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } Spring容器装配Bean的三种方式 隐式的Bean发现机制和自动装配Spring从两个角度来实现自动化装配;组件扫描(Spring自动发现应用中上下文所需要的创建的Bean),自动装配(Spring自动满足Bean之间的依赖) 使用@Component将普通Java类配置成SpringBean 使用@Autowired(自动装配)使Spring满足Bean的依赖 @Component public class User { @Autowired private Article article; public void action() { article.action(); } } 基于Java的Bean装配使用 @Bean 注解将方法返回的实例对象添加到上下文中 在@Bean返回的实例对象中可以通过构造器注入传入相关依赖 @Configuration @ComponentScan("com.jimisun") public class WebConfig { @Bean public User user() { return new User(myArticle()); } @Bean public MyArticle myArticle() { return new MyArticle(); } } 基于XML的Bean装配对于在XML中进行配置可能使我们经常使用的,在以前的Spring版本中几乎我们都是使用XML进行配置Spring,下面我们简单来看一下。 注意:在实际应用中如何不想被海量的标签埋没前,你应当优先使用隐式的Bean发现机制和自动装配和在Java中进行装配,最后再选择使用在XML中配置。 最后值得一提的是在实际项目中我们通常都会选择组合使用隐式的Bean发现机制和Java中进行装配进行组合 隐式的Bean发现机制和XML配置进行组合 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |