使用 @Bean 注入一个 bean 但无法通过 @ConditionalOnBean 的检查
use @Bean inject a bean but could't pass check about @ConditionalOnBean
当我注释掉@ConditionalOnBean(name = "customRedisConnectionFactory")
行时,函数被执行,customRedisConnectionFactory
是我注入的对象。但是当我启用这一行时,该方法不会执行。我想知道原因。谁能帮我解答一下。
Redis配置
@Configuration
@ConditionalOnClass(RedisOperations.class)
@AutoConfigureBefore({CacheAutoConfiguration.class})
public class RedisConfig {
@Bean(name = "customRedisConnectionFactory")
public RedisConnectionFactory customRedisConnectionFactory(){
RedisStandaloneConfiguration redisStandaloneConfiguration=new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setDatabase(12);
redisStandaloneConfiguration.setHostName("127.0.0.1");
redisStandaloneConfiguration.setPassword("yichen");
redisStandaloneConfiguration.setPort(6379);
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration);
return jedisConnectionFactory;
}
}
自定义RedisCacheManager配置
@Configuration
@AutoConfigureAfter({CacheAutoConfiguration.class})
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties({RedisProperties.class, CacheProperties.class, RedisCacheExpiresProperties.class})
public class CustomRedisCacheManagerConfiguration {
private final CacheProperties cacheProperties;
public CustomRedisCacheManagerConfiguration(CacheProperties cacheProperties) {
this.cacheProperties = cacheProperties;
}
@Bean(name = "serviceRedisCacheManager")
@ConditionalOnBean(name = "customRedisConnectionFactory")
public RedisCacheManager serviceRedisCacheManager(
@Qualifier("customRedisConnectionFactory") RedisConnectionFactory customRedisConnectionFactory,
RedisCacheExpiresProperties redisCacheExpiresProperties) {
RedisCacheManager.RedisCacheManagerBuilder builder =
RedisCacheManager.builder(customRedisConnectionFactory).cacheDefaults(determineConfigurationDefault());
Map<String, Long> cacheConfigurations = redisCacheExpiresProperties.getCacheExpires();
if (cacheConfigurations != null && cacheConfigurations.size() > 0) {
Map<String, RedisCacheConfiguration> redisCacheConfigurations = new HashMap<>();
for (String cacheName : cacheConfigurations.keySet()) {
Assert.notNull(cacheName, "CacheName must not be null!");
long ttl = cacheConfigurations.get(cacheName);
Assert.isTrue(ttl > 0, "Expire must not be null!");
RedisCacheConfiguration redisCacheConfiguration = determineConfiguration(cacheName, ttl);
redisCacheConfigurations.put(cacheName, redisCacheConfiguration);
}
builder.withInitialCacheConfigurations(redisCacheConfigurations);
}
return builder.build();
}
private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfigurationDefault() {
CacheProperties.Redis redisProperties = this.cacheProperties.getRedis();
org.springframework.data.redis.cache.RedisCacheConfiguration config =
org.springframework.data.redis.cache.RedisCacheConfiguration.defaultCacheConfig();
config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
if (redisProperties.getTimeToLive() != null) {
config = config.entryTtl(redisProperties.getTimeToLive());
}
if (redisProperties.getKeyPrefix() != null) {
config = config.prefixKeysWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
config = config.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
config = config.disableKeyPrefix();
}
return config;
}
private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(String cacheName,long ttl) {
org.springframework.data.redis.cache.RedisCacheConfiguration config =
org.springframework.data.redis.cache.RedisCacheConfiguration.defaultCacheConfig();
config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
config = config.entryTtl(Duration.ofSeconds(ttl));
config = config.disableCachingNullValues();
return config;
}
}
application.properties
spring.redis.password=yichen
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.database=10
spring.redis.max.idle=10
spring.redis.max.total=30
spring.redis.max.wait.mills=-1
spring.cache.redis.time-to-live=60000
spring.cache.redis.key-prefix=test
spring.cache.redis.cache-expires.c3m=180
spring.cache.redis.cache-expires.c5m=300
spring.cache.redis.cache-expires.c10m=600
spring.cache.redis.cache-expires.c30m=1800
spring.cache.redis.cache-expires.c24h=86400
spring.cache.redis.cache-expires.c7d=604800
spring.cache.redis.cache-expires.c30d=2592000
RedisCacheExpiresProperties
@ConfigurationProperties(prefix = "spring.cache.redis")
public class RedisCacheExpiresProperties {
private Map<String, Long> cacheExpires;
public Map<String, Long> getCacheExpires() {
return cacheExpires;
}
public void setCacheExpires(Map<String, Long> cacheExpires) {
this.cacheExpires = cacheExpires;
}
}
我认为这两个配置 class(RedisConfig
和 CustomRedisCacheManagerConfiguration
)的自动配置顺序可能有问题。确保将 class 注册为自动配置 class 并且 RedisConfig
在 CustomRedisCacheManagerConfiguration
之前自动配置。
当我尝试用 @ConditionalOnBean(type = "RedisConnectionFactory")
替换 @DependsOn("customRedisConnectionFactory")
时,它成功执行了。
它们的区别和实现细节有待研究
当我注释掉@ConditionalOnBean(name = "customRedisConnectionFactory")
行时,函数被执行,customRedisConnectionFactory
是我注入的对象。但是当我启用这一行时,该方法不会执行。我想知道原因。谁能帮我解答一下。
Redis配置
@Configuration
@ConditionalOnClass(RedisOperations.class)
@AutoConfigureBefore({CacheAutoConfiguration.class})
public class RedisConfig {
@Bean(name = "customRedisConnectionFactory")
public RedisConnectionFactory customRedisConnectionFactory(){
RedisStandaloneConfiguration redisStandaloneConfiguration=new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setDatabase(12);
redisStandaloneConfiguration.setHostName("127.0.0.1");
redisStandaloneConfiguration.setPassword("yichen");
redisStandaloneConfiguration.setPort(6379);
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration);
return jedisConnectionFactory;
}
}
自定义RedisCacheManager配置
@Configuration
@AutoConfigureAfter({CacheAutoConfiguration.class})
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties({RedisProperties.class, CacheProperties.class, RedisCacheExpiresProperties.class})
public class CustomRedisCacheManagerConfiguration {
private final CacheProperties cacheProperties;
public CustomRedisCacheManagerConfiguration(CacheProperties cacheProperties) {
this.cacheProperties = cacheProperties;
}
@Bean(name = "serviceRedisCacheManager")
@ConditionalOnBean(name = "customRedisConnectionFactory")
public RedisCacheManager serviceRedisCacheManager(
@Qualifier("customRedisConnectionFactory") RedisConnectionFactory customRedisConnectionFactory,
RedisCacheExpiresProperties redisCacheExpiresProperties) {
RedisCacheManager.RedisCacheManagerBuilder builder =
RedisCacheManager.builder(customRedisConnectionFactory).cacheDefaults(determineConfigurationDefault());
Map<String, Long> cacheConfigurations = redisCacheExpiresProperties.getCacheExpires();
if (cacheConfigurations != null && cacheConfigurations.size() > 0) {
Map<String, RedisCacheConfiguration> redisCacheConfigurations = new HashMap<>();
for (String cacheName : cacheConfigurations.keySet()) {
Assert.notNull(cacheName, "CacheName must not be null!");
long ttl = cacheConfigurations.get(cacheName);
Assert.isTrue(ttl > 0, "Expire must not be null!");
RedisCacheConfiguration redisCacheConfiguration = determineConfiguration(cacheName, ttl);
redisCacheConfigurations.put(cacheName, redisCacheConfiguration);
}
builder.withInitialCacheConfigurations(redisCacheConfigurations);
}
return builder.build();
}
private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfigurationDefault() {
CacheProperties.Redis redisProperties = this.cacheProperties.getRedis();
org.springframework.data.redis.cache.RedisCacheConfiguration config =
org.springframework.data.redis.cache.RedisCacheConfiguration.defaultCacheConfig();
config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
if (redisProperties.getTimeToLive() != null) {
config = config.entryTtl(redisProperties.getTimeToLive());
}
if (redisProperties.getKeyPrefix() != null) {
config = config.prefixKeysWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
config = config.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
config = config.disableKeyPrefix();
}
return config;
}
private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(String cacheName,long ttl) {
org.springframework.data.redis.cache.RedisCacheConfiguration config =
org.springframework.data.redis.cache.RedisCacheConfiguration.defaultCacheConfig();
config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
config = config.entryTtl(Duration.ofSeconds(ttl));
config = config.disableCachingNullValues();
return config;
}
}
application.properties
spring.redis.password=yichen
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.database=10
spring.redis.max.idle=10
spring.redis.max.total=30
spring.redis.max.wait.mills=-1
spring.cache.redis.time-to-live=60000
spring.cache.redis.key-prefix=test
spring.cache.redis.cache-expires.c3m=180
spring.cache.redis.cache-expires.c5m=300
spring.cache.redis.cache-expires.c10m=600
spring.cache.redis.cache-expires.c30m=1800
spring.cache.redis.cache-expires.c24h=86400
spring.cache.redis.cache-expires.c7d=604800
spring.cache.redis.cache-expires.c30d=2592000
RedisCacheExpiresProperties
@ConfigurationProperties(prefix = "spring.cache.redis")
public class RedisCacheExpiresProperties {
private Map<String, Long> cacheExpires;
public Map<String, Long> getCacheExpires() {
return cacheExpires;
}
public void setCacheExpires(Map<String, Long> cacheExpires) {
this.cacheExpires = cacheExpires;
}
}
我认为这两个配置 class(RedisConfig
和 CustomRedisCacheManagerConfiguration
)的自动配置顺序可能有问题。确保将 class 注册为自动配置 class 并且 RedisConfig
在 CustomRedisCacheManagerConfiguration
之前自动配置。
当我尝试用 @ConditionalOnBean(type = "RedisConnectionFactory")
替换 @DependsOn("customRedisConnectionFactory")
时,它成功执行了。
它们的区别和实现细节有待研究