Conditional注解

此注解用于配合 @Bean 注解, 限定Bean注解的条件: 如果满足条件, 响应的Bean才会放入容器; 否则不会!

springboot大量应用此注解!

Conditional注解能够在满足某条件时才初始化Bean, 条件就是实现了Condition接口的match办法的逻辑!本实例就是依据VM option运行时传入一个参数 -Dspring.profiles.active=xxx, 依据xxx是dev还是product来决定生成的对象User是 admin还是user01

(1). VM options减少参数

-Dspring.profiles.active=product
(C:UsersweijuAppDataRoamingTyporatypora-user-imagesimage-20200713180310059.png)

(2). 测试代码:

@Testpublic void testConditinalBean() {    ApplicationContext ctx = new AnnotationConfigApplicationContext(ConditionalConfig.class);    Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println);    Environment environment = ctx.getEnvironment();    String profile = environment.getProperty("spring.profiles.active");    System.out.println(profile);    User user = ctx.getBean(User.class);    System.out.println(user);}

(3). 输入:

User-初始化!
conditionalConfig
uProduct
product
User{name='user01', passwd='realP@sswd', online=true}

(4). ConditionalConfig.java:

能够看到: ConditionalConfig中, 应用了注解: @Conditional({ConditionalDev.class}) @Conditional({ConditionalProduct.class}) 两个@Bean, 然而实际上初始化和输入的只有 product, 是-D参数的抉择!!

package com.niewj.config;import com.niewj.bean.User;import com.niewj.condition.ConditionalDev;import com.niewj.condition.ConditionalProduct;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Conditional;import org.springframework.context.annotation.Configuration;@Configurationpublic class ConditionalConfig {    @Conditional({ConditionalDev.class})    @Bean("uDev")    public User userDev(){        return new User("admin", "admin", false);    }    @Conditional({ConditionalProduct.class})    @Bean("uProduct")    public User userProduct(){        return new User("user01", "realP@sswd", true);    }}

(5). User.java实体类:

package com.niewj.bean;import lombok.Data;@Datapublic class User {    private String name;    private String passwd;    private boolean online ;    public User(String name, String passwd, boolean online){        System.out.println("User-初始化!");        this.name = name;        this.passwd = passwd;        this.online = online;    }    @Override    public String toString() {        return "User{" +                "name='" + name + '\'' +                ", passwd='" + passwd + '\'' +                ", online=" + online +                '}';    }}

(6). 外围: Condition接口实现

ConditionalDev + ConditionalProduct

package com.niewj.condition;import com.niewj.ConstUtil;import org.springframework.context.annotation.Condition;import org.springframework.context.annotation.ConditionContext;import org.springframework.core.type.AnnotatedTypeMetadata;/** * spring.profiles.active=dev 时满足条件 */public class ConditionalDev implements Condition {    @Override    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {        String profile = context.getEnvironment().getProperty(ConstUtil.PROFILES_ACTIVE);        if (ConstUtil.DEV.equalsIgnoreCase(profile)) {            return true;        }        return false;    }}

ConditionalDev在条件: -Dspring.profiles.active=dev时返回true!

ConditionalProduct在条件: -Dspring.profiles.active=product时返回true!

可见, 能够依据某个传入参数来抉择是否初始化某个Bean, 比方: 用来辨别生产和dev环境~~

package com.niewj.condition;import com.niewj.ConstUtil;import org.springframework.context.annotation.Condition;import org.springframework.context.annotation.ConditionContext;import org.springframework.core.type.AnnotatedTypeMetadata;/** * profile=product 时满足条件 */public class ConditionalProduct implements Condition {    @Override    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {        String profile = context.getEnvironment().getProperty(ConstUtil.PROFILES_ACTIVE);        if (ConstUtil.PRODUCT.equalsIgnoreCase(profile)) {            return true;        }        return false;    }}

(7). 小结:

  1. @Conditional 注解能够配合@Bean注解, 在Springboot中大量利用!
  2. @Conditional注解能够用于 办法 也能够用于类, 用在类上示意: 所有办法限定!!
  3. 须要标注具体的Condition实现类: 具体逻辑实现在 match办法里! 不同的条件实现不同的Condition子类!