我在公共模块自定义了一个RedisConfig
@Configuration
@ConditionalOnProperty(value = "jsy.service.enable", havingValue = "true")
public class RedisConfig {
@Resource
private RedisConnectionFactory factory;
@Value("${spring.redis.port}")
private Integer redisPort;
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.password}")
private String redisPassword;
@Value("${spring.redis.database}")
private Integer redisDatabase;
@Value("${jsy.redis.annotation.cacheTimeout}")
private Integer cacheTimeout;
@Bean
public RedissonClient redissonClient(){
Config config = new Config();
SingleServerConfig singleServerConfig = config.useSingleServer();
singleServerConfig.setAddress("redis://"+ redisHost +":" + redisPort);
singleServerConfig.setDatabase(redisDatabase);
singleServerConfig.setPassword(redisPassword);
return Redisson.create(config);
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
/**
* RedisSerializer
* 自定义序列化类参照:https://docs.spring.io/spring-data/redis/docs/current/api/
* GenericJackson2JsonRedisSerializer - 基于通用Jackson的2 RedisSerializer,objects使用动态类型映射到JSON。
* GenericToStringSerializer - 通用字符串转为byte [](并返回)序列化器。依靠SpringConversionService将对象转换为String,反之亦然。使用指定的字符集(默认为UTF-8)将字符串转换为字节,反之亦然。注意:如果将类定义为Spring bean,则转换服务初始化会自动发生。注意:不会以任何特殊方式处理null,将所有内容委派给容器。
* Jackson2JsonRedisSerializer - 该转换器可用于绑定到类型化的bean或未类型化的HashMap实例。 注意:空对象被序列化为空数组,反之亦然。
* JdkSerializationRedisSerializer - Java序列化Redis序列化器。代表默认值(基于Java)serializer和 DefaultDeserializer。这serializer可以用customClassLoader或own构造 converters。
* OxmSerializer - Spring的O / X映射之上的Serializer适配器。将序列化/反序列化委托给OXMMarshaller 和Unmarshaller。注意:空对象被序列化为空数组,反之亦然。
* StringRedisSerializer - 简单String到byte [](和返回)串行器。Strings 使用指定的字符集(默认为UTF-8)转换为字节,反之亦然。与Redis的交互主要通过字符串进行时很有用。由于空字符串是有效的键/值,因此不执行任何null转换。
*/
@Bean
public RedisCacheManager defaultCacheManager(RedisConnectionFactory redisConnectionFactory){
//设置CacheManager的值序列化方式为json序列化
RedisSerializer<Object> jsonSerializer = new GenericJackson2JsonRedisSerializer();
RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair
.fromSerializer(jsonSerializer);
RedisCacheConfiguration defaultCacheConfig= RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(pair);
defaultCacheConfig = defaultCacheConfig.serializeValuesWith(
RedisSerializationContext
.SerializationPair
.fromSerializer(jsonSerializer)
).entryTtl(Duration.ofSeconds(this.cacheTimeout));
return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(defaultCacheConfig).build();
}
}
然后我在业务模块引入了公共模块
然后业务的控制器使用@Cacheable注解,使用自定义的defaultCacheManager
令人奇怪的是,以上公共模块的redisTemplate 实例能在业务模块找到,但是我自定义的defaultCacheManager实例无法在Spring容器找到,
但是在加载时,defaultCacheManager这个Bean是经过加载的,问题是无法装载至Spring
以下是我在业务模块找到的所有Bean名称
以上配置的defaultCacheManager在单模块中使用是正常的
业务模块控制器@Cacheable注解
@Login
@GetMapping("/rotation")
@Cacheable(value = "inform:rotation", key = "#communityId", unless = "#result.data == null or #result.data.size() == 0", condition = "#communityId > 0", cacheManager = "defaultCacheManager")
@ApiOperation("社区轮播消息")
public CommonResult<List<PushInformEntity>> rotationCommunityInform(@RequestParam Long communityId) {
...
}
请求时 无法找到公共模块定义的defaultCacheManager
NoSuchBeanDefinitionException: No bean named 'defaultCacheManager' available: No matching CacheManager bean found for qualifier 'defaultCacheManager' - neither qualifier match nor bean name match!
我公共模块配置的spring.cache.type = redis