Spring Boot2 系列(二) -自动化配置的原理

自动化配置是怎么实现的 - starter
对,但-这里边有一个非常关键的点,那就是条件注解

条件注解并非一个新事物,这是一个存在于 Spring 中的东西,
我们在 Spring 中常用的 profile 实际上就是条件注解的一个特殊化

核心思想就是当满足某种条件的时候,某个 Bean 才会生效,而正是这一特性,支撑起了 Spring Boot 的自动化配置

spring中条件注解的用法

首先创建一个maven项目

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
    </dependencies>

定义一个接口 然后写2个实现类

public interface Food {
    String showName();
}


public class Rice implements Food {
    public String showName() {
        return "米饭";
    }
}

public class Noodles implements Food {
    public String showName() {
        return "面条";
    }
}

再创建实现类的条件类

意思很简单
实现Condition 重写里面的 match方法 做条件属性判断

public class NoodlesCondition implements Condition {
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        return conditionContext.getEnvironment().getProperty("people").equals("北方人");
    }
}

public class RiceCondition implements Condition {
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        return conditionContext.getEnvironment().getProperty("people").equals("南方人");
    }
}

哪个条件得到满足,一会就会创建哪个 Bean

接下来就配置实现了

@Configuration
public class JavaConfig {

    @Bean("food")
    @Conditional(RiceCondition.class)
    Food rice(){
        return new Rice();
    }

    @Bean("food")
    @Conditional(NoodlesCondition.class)
    Food noodles(){
        return new Noodles();
    }

}

需要注意的是

  • 两个 Bean 的返回值都为其父类对象 Food
  • 当 @Conditional 注解中配置的条件类的 matches 方法返回值为 true 时,对应的 Bean 就会生效

测试

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext();
        acac.getEnvironment().getSystemProperties().put("people","南方人");
        acac.register(JavaConfig.class);
        acac.refresh();
        Food food = (Food) acac.getBean("food");
        System.out.println(food.showName());
    }
}

没错 - 南方人对应返回输出 米饭

进化写法

  • 不再需要Condition类
  • 把 @Conditional()注解改为@Profile()注解,里面写条件就行了
@Configuration
public class JavaConfig {

    @Bean("food")
    @Profile("南方人")
    Food rice(){
        return new Rice();
    }

    @Bean("food")
    @Profile("北方人")
    Food noodles(){
        return new Noodles();
    }
}

这样看起来 @Profile 注解貌似比 @Conditional 注解还要方便,那么 @Profile 注解到底是什么实现的呢?

点开来看看
在这里插入图片描述
可以看到 @Profile() 里面也是有 @Conditional()注解 的
在这里插入图片描述

看到这里就明白了,其实还是我们在条件注解中写的那一套东西,只不过 @Profile 注解自动帮我们实现了而已。

@Profile 虽然方便,但是不够灵活,因为具体的判断逻辑不是我们自己实现的。
而 @Conditional 则比较灵活

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值