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:\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). 小结:
- @Conditional 注解可以配合@Bean注解, 在Springboot中大量应用!
- @Conditional注解可以用于 方法 也可以用于类, 用在类上表示: 所有方法限定!!
- 需要标注具体的Condition实现类: 具体逻辑实现在 match方法里! 不同的条件实现不同的Condition子类!
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 hi@niewj.com