转载

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

@Bean+@Conditional:

在满足某条件后才往spring容器中注入bean, 不满足则忽略!

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

  1. VM options增加参数: -Dspring.profiles.active=product

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

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);
}

输出:

User-初始化!

conditionalConfig

uProduct

product

User{name='user01', passwd='realP@sswd', online=true}

  1. 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);
    }
}

4.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 +
                '}';
    }
}

5.核心: 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;
    }
}

小结:

  1. @Conditional 注解可以配合@Bean注解, 在Springboot中大量应用!
  2. @Conditional注解可以用于 方法 也可以用于类, 用在类上表示: 所有方法限定!!
  3. 需要标注具体的Condition实现类: 具体逻辑实现在 match方法里! 不同的条件实现不同的Condition子类!
原文  https://segmentfault.com/a/1190000023210213
正文到此结束
Loading...