Spring Boot2 系列教程(七)理解自动化配置的原理

public String showName() {

return “米饭”;

}

}

public class Noodles implements Food {

public String showName() {

return “面条”;

}

}

分别是 Rice 和 Noodles 两个类,两个类实现了 showName 方法,然后分别返回不同值。

接下来再分别创建 Rice 和 Noodles 的条件类,如下:

public class NoodlesCondition implements Condition {

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

return context.getEnvironment().getProperty(“people”).equals(“北方人”);

}

}

public class RiceCondition implements Condition {

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

return context.getEnvironment().getProperty(“people”).equals(“南方人”);

}

}

在 matches 方法中做条件属性判断,当系统属性中的 people 属性值为 ‘北方人’ 的时候,NoodlesCondition 的条件得到满足,当系统中 people 属性值为 ‘南方人’ 的时候,RiceCondition 的条件得到满足,换句话说,哪个条件得到满足,一会就会创建哪个 Bean 。

接下来我们来配置 Rice 和 Noodles :

@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,这不是巧合,而是有意取的。两个 Bean 的返回值都为其父类对象 Food。

  • 每个 Bean 上都多了 @Conditional 注解,当 @Conditional 注解中配置的条件类的 matches 方法返回值为 true 时,对应的 Bean 就会生效。

配置完成后,我们就可以在 main 方法中进行测试了:

public class Main {

public static void main(String[] args) {

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();

ctx.getEnvironment().getSystemProperties().put(“people”, “南方人”);

ctx.register(JavaConfig.class);

ctx.refresh();

Food food = (Food) ctx.getBean(“food”);

System.out.println(food.showName());

}

}

首先我们创建一个 AnnotationConfigApplicationContext 实例用来加载 Java 配置类,然后我们添加一个 property 到 environment 中,添加完成后,再去注册我们的配置类,然后刷新容器。容器刷新完成后,我们就可以从容器中去获取 food 的实例了,这个实例会根据 people 属性的不同,而创建出来不同的 Food 实例。

这个就是 Spring 中的条件注解。

进化

==============================================================

条件注解还有一个进化版,那就是 Profile。我们一般利用 Profile 来实现在开发环境和生产环境之间进行快速切换。其实 Profile 就是利用条件注解来实现的。

还是刚才的例子,我们用 Profile 来稍微改造一下:

首先 Food、Rice 以及 Noodles 的定义不用变,条件注解这次我们不需要了,我们直接在 Bean 定义时添加 @Profile 注解,如下:

@Configuration

public class JavaConfig {

@Bean(“food”)

@Profile(“南方人”)

Food rice() {

return new Rice();

}

@Bean(“food”)

@Profile(“北方人”)

Food noodles() {

return new Noodles();

}

}

这次不需要条件注解了,取而代之的是 @Profile 。然后在 Main 方法中,按照如下方式加载 Bean:

public class Main {

public static void main(String[] args) {

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();

ctx.getEnvironment().setActiveProfiles(“南方人”);

ctx.register(JavaConfig.class);

ctx.refresh();

Food food = (Food) ctx.getBean(“food”);

System.out.println(food.showName());

}

}

效果和上面的案例一样。

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

我们来看一下 @Profile 的定义:

@Target({ElementType.TYPE, ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Conditional(ProfileCondition.class)

public @interface Profile {

String[] value();

独家面经总结,超级精彩

本人面试腾讯,阿里,百度等企业总结下来的面试经历,都是真实的,分享给大家!

image

image

image

image

Java面试准备

准确的说这里又分为两部分:

  1. Java刷题
  2. 算法刷题

Java刷题:此份文档详细记录了千道面试题与详解;

image

image

加入社区:https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0
587)]

[外链图片转存中…(img-3w016BUV-1725719494587)]

Java面试准备

准确的说这里又分为两部分:

  1. Java刷题
  2. 算法刷题

Java刷题:此份文档详细记录了千道面试题与详解;

[外链图片转存中…(img-mKQo9c7j-1725719494588)]

[外链图片转存中…(img-AUXIeLmh-1725719494589)]

加入社区:https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值