spring注解驱动开发-(4)-Conditional注解

  1. Conditional注解
    1. (1). VM options增加参数
    2. (2). 测试代码:
    3. (3). 输出:
    4. (4). ConditionalConfig.java:
    5. (5). User.java实体类:
    6. (6). 核心: Condition接口实现
    7. (7). 小结:

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
image.png(C:\Users\weiju\AppData\Roaming\Typora\typora-user-images\image-20200713180310059.png)

(2). 测试代码:

@Test
public 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;

@Configuration
public 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;

@Data
public 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子类!

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 hi@niewj.com

×

喜欢就点赞,疼爱就打赏