RedisConfig配置注入不进项目中

您所在的位置:网站首页 service注入不进去 RedisConfig配置注入不进项目中

RedisConfig配置注入不进项目中

2023-01-02 15:02| 来源: 网络整理| 查看: 265

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.png

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 意思是两个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