@ConditionalOnProperty注解控制配置文件是否生效

该博客介绍了如何使用@Configuration和@ConditionalOnProperty注解来控制配置生效,基于应用属性动态加载配置。同时展示了如何配置Redis作为缓存管理器,包括RedisTemplate的配置和缓存序列化策略,以及启用缓存@EnableCaching的条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个注解能够控制某个configuration是否生效。具体操作是通过其两个属性name以及havingValue来实现的,其中name用来从application.properties中读取某个属性值,如果该值为空,则返回false;如果值不为空,则将该值与havingValue指定的值进行比较,如果一样则返回true;否则返回false。如果返回值为false,则该configuration不生效;为true则生效。

@Configuration
//如果synchronize在配置文件中并且值为true
@ConditionalOnProperty(name = "synchronize", havingValue = "true")
public class SecondDatasourceConfig {

    @Bean(name = "SecondDataSource")
    @Qualifier("SecondDataSource")
    @ConfigurationProperties(prefix = "spring.second.datasource")
    public DataSource jwcDataSource() {
        return DataSourceBuilder.create().build();
    }
}

@EnableCaching  //启用缓存注解
@Configuration
@ConditionalOnProperty(name = "current.cache.enable", havingValue = "true")
public class RedisConfig extends CachingConfigurerSupport {

    /**
     * 注入生成key的策略(作用于注解注解缓存)
     */
    @Bean(name = "customKeyGenerator")
    public KeyGenerator keyGenerator() {
        return new RedisCacheKeyGenerator();
    }

    @Primary
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        // 对象的序列化
        RedisSerializationContext.SerializationPair<Object> valueSerializationPair
                = RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer());
        // 全局redis缓存过期时间。默认1天
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofDays(1))
//                .serializeKeysWith()
                .serializeValuesWith(valueSerializationPair);

        return new RedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(factory), redisCacheConfiguration);
    }

    /**
     * RedisTemplate配置
     * @param factory redis链接工厂
     * @return RedisTemplate
     */
    @Bean(name = "redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();

        // 设置序列化,key采用redisSerializer,value采用jackson2JsonRedisSerializer
        template.setConnectionFactory(factory);
        template.setKeySerializer(redisSerializer);
        template.setValueSerializer(jackson2JsonRedisSerializer());
        template.setHashKeySerializer(redisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }


    private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper());
        return jackson2JsonRedisSerializer;
    }

    private ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        // 解决jackson2无法反序列化LocalDateTime的问题
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());
        return objectMapper;
    }


}

<think>好的,我现在需要解释Spring框架中的@Conditional和@ConditionalOnProperty注解。首先,我得回忆一下这两个注解的作用和区别。用户可能对Spring的条件化配置不太熟悉,所以要从基础讲起。 首先,@Conditional是Spring 4.0引入的核心注解,用于根据特定条件决定是否注册某个Bean。这个注解需要配合实现了Condition接口的类来使用。比如,用户可以定义一个条件类,重写matches方法,根据上下文环境决定是否创建Bean。 接下来是@ConditionalOnProperty,它属于Spring Boot的条件化注解,基于配置属性的存在与否来控制Bean的创建。用户可能在配置文件中设置某个属性,通过这个注解来启用或禁用特定的配置类或Bean。 需要区分两者的不同:@Conditional更通用,需要自定义条件逻辑;而@ConditionalOnProperty是预定义好的,专注于处理配置属性,使用起来更方便。可能还要提到@ConditionalOnProperty的常用参数,比如prefix、name、havingValue等,并给出例子说明如何根据配置文件中的属性来决定Bean的加载。 还要注意结构清晰,分步骤讲解。可能需要先介绍@Conditional,然后引出Spring Boot提供的各种@ConditionalOn*注解,再具体到@ConditionalOnProperty。同时,要确保LaTeX格式正确,比如行内公式用$...$,独立公式用$$...$$,但在这个问题中可能用不到数学公式,但需要遵循用户的格式要求,比如变量或代码块可能需要用行内格式。 检查是否有理解错误的地方。比如,@ConditionalOnProperty是否属于Spring Boot特有?是的,它是Spring Boot的条件注解,而@Conditional是Spring框架本身的。还要确认示例代码的正确性,是否需要避免使用Markdown,但用户没有禁止代码块,可能需要用文字描述或伪代码。 最后,确保用中文回答,语言通顺,结构清晰,分点解释,帮助用户逐步理解这两个注解的用途和用法。</think>Spring框架中的`@Conditional`和`@ConditionalOnProperty`注解用于实现条件化配置。以下是分步说明: --- ### 一、`@Conditional` 注解 #### 1. 核心作用 - **条件化加载Bean**:根据特定条件决定是否注册Bean到Spring容器。 - **自定义条件**:需配合实现`Condition`接口的类。 #### 2. 实现步骤 **(1) 定义条件类** ```java public class CustomCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // 自定义逻辑,返回true则加载Bean return System.getProperty("os.name").contains("Windows"); } } ``` **(2) 应用注解** ```java @Configuration public class AppConfig { @Bean @Conditional(CustomCondition.class) public MyBean myBean() { return new MyBean(); } } ``` - **结果**:仅当系统为Windows时,`MyBean`才会被注册。 --- ### 二、`@ConditionalOnProperty` 注解 #### 1. 核心作用 - **基于配置属性控制Bean**:根据配置文件(如`application.properties`)中的属性值决定是否加载Bean。 - **Spring Boot特有**:属于`spring-boot-autoconfigure`模块。 #### 2. 关键参数 - `prefix`:属性前缀。 - `name`:属性名。 - `havingValue`:匹配的目标值。 - `matchIfMissing`:属性不存在时的默认行为(默认为`false`)。 #### 3. 典型用法 **(1) 配置文件示例** ```properties # application.properties myapp.feature.enabled=true ``` **(2) 注解应用** ```java @Configuration @ConditionalOnProperty( prefix = "myapp.feature", name = "enabled", havingValue = "true", matchIfMissing = false ) public class FeatureConfig { @Bean public FeatureService featureService() { return new FeatureService(); } } ``` - **结果**:仅当`myapp.feature.enabled=true`时,`FeatureConfig`配置类生效,注册`FeatureService`。 --- ### 三、区别对比 | 特性 | `@Conditional` | `@ConditionalOnProperty` | |---------------------|--------------------------------|---------------------------------| | **所属框架** | Spring Core | Spring Boot | | **灵活性** | 高(需自定义逻辑) | 低(专注属性匹配) | | **适用场景** | 复杂条件(如系统环境、类路径) | 简单属性开关控制 | --- ### 四、联合使用示例 ```java @Configuration public class AdvancedConfig { @Bean @ConditionalOnProperty(name = "cache.enabled", havingValue = "true") @Conditional(CacheProviderAvailableCondition.class) public CacheService cacheService() { return new RedisCacheService(); } } ``` - **逻辑**:仅当`cache.enabled=true`且缓存服务提供者存在时,注册`CacheService`。 --- ### 五、常见问题 1. **属性名优先级**:`name`参数支持数组,如`name={"prop1", "prop2"}`,按顺序匹配首个存在的属性。 2. **松散绑定**:属性名支持松散匹配(如`my-prop`和`myProp`等效)。 3. **多条件组合**:通过`@Conditional`组合多个条件类,或使用`AllNestedConditions`实现复杂逻辑。 --- 通过以上步骤,可灵活控制Spring Bean的加载行为,实现按需配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值