使用 @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(RedisConfigCustomRedisCacheManagerConfiguration)的自动配置顺序可能有问题。确保将 class 注册为自动配置 class 并且 RedisConfigCustomRedisCacheManagerConfiguration 之前自动配置。

当我尝试用 @ConditionalOnBean(type = "RedisConnectionFactory") 替换 @DependsOn("customRedisConnectionFactory") 时,它成功执行了。 它们的区别和实现细节有待研究