@Conditional注解详解
在使⽤Spring框架开发应⽤的过程中,⼤家都知道使⽤Spring开发应⽤程序,我们应⽤程序中⼤多数的Bean都是通过Spring的IOC容器来管理。将Bean注⼊到Spring IOC容器中的⽅式多种多样,可以通过组件扫描@ComponentScan注⼊、可以通过@Configuration和
@Bean注⼊等。
本⽂我们要陈述的是如何根据不同的条件来判定到底注⼊那个Bean,即@Conditional注解的⽤法。
1、@Conditional介绍
⾸先我们先了解⼀下@Conditional注解,@Conditional是Spring4新提供的注解,它的作⽤是按照⼀定的条件进⾏判断,需要注⼊的Bean满⾜给定条件才可以注⼊到Spring IOC容器中。
我们先来看⼀下@Conditional注解的定义:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
/**
* All {@link Condition Conditions} that must {@linkplain Condition#matches match}
* in order for the component to be registered.
*/
Class<? extends Condition>[] value();
}
从注解的定义我们可以看到,使⽤该注解我们需要传⼊的是⼀个Class数组,并且这些Class必须实现Condition接⼝,Condition接⼝定义如下:
@FunctionalInterface
public interface Condition {
/**
* Determine if the condition matches.
* @param context the condition context
* @param metadata metadata of the {@link ype.AnnotationMetadata class}
* or {@link ype.MethodMetadata method} being checked
* @return {@code true} if the condition matches and the component can be registered,
* or {@code false} to veto the annotated component's registration
*/
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
从接⼝定义我们不难发现,实现Condition接⼝必须实现matches⽅法,matches⽅法返回的是⼀个boolean类型的数据,即返回true,代表@Conditional注解的Bean可以被注⼊到Spring IOC容器,返回false,@Conditional注解的Bean就不会被注⼊到Spring IOC容器。
2、@Conditional实例演⽰
⼀般情况下,我们的项⽬在不同阶段可能部署在不同的环境,⽐如开发阶段是部署在测试环境,验收阶段是部署在UAT环境,⽣产阶段是部署在⽣产环境。部署在不同的环境,我们的数据库链接肯定不⼀样,因此我们就以在不同环境获取不同数据库链接为例,来说明
@Conditional注解的应⽤。
我们的例⼦要实现的是在配置⽂件中,如果我们配置当前环境为UAT环境,则返回UAT环境的数据库链接,如果配置的是⽣产环境,则返回⽣产环境的数据库链接。
⾸先是创建项⽬并添加必要的依赖,这⾥就不给出依赖配置的代码了,参考。
在src/main/resources⽬录下创建配置⽂件Env.properties,⽤来配置环境信息。
创建entity包,写⼊测试数据类DataBase并重写toString⽅法,因为仅做演⽰,我们就简单些⼏个属性就可以了。
public class DataBase {
private String host;
private String user;
private String password;
public DataBase() {}
public DataBase(String host,String user,String password) {
this.host=host;
this.user=user;
this.password=password;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
spring ioc注解public String toString() {
return "DataBase [host="+host+",user="+ user +",password="+ password +"]";
}
}
创建condition包,写⼊Bean注⼊的判定条件,因为我们要实现的是在配置⽂件中,如果我们配置当前环境为UAT环境,则返回UAT环境的数据库链接,如果配置的是⽣产环境,则返回⽣产环境的数据库链接,所以我们需要两个条件,⼀个判定UAT环境的条件UatCondition,⼀个判定⽣产环境的条件ProCondition。
//UAT环境的条件UatCondition
public class UatCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment env = Environment();
Property("env").equals("UAT")){
return true;
}
return false;
}
}
//⽣产环境的条件ProCondition
public class ProCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment env = Environment();
Property("env").equals("Pro")){
return true;
}
return false;
}
}
创建config包,创建配置类DataBaseConfig通过注解@Configuration和@Bean向容器中注⼊组件。
//告诉Spring这是⼀个配置类
@Configuration
//将properties配置⽂件中的值存储到Spring的 Environment中,Environment接⼝提供⽅法去读取配置⽂件中的值,参数是properties⽂件中定义的key值。@PropertySource("classpath:Env.properties")
public class DataBaseConfig {
@Bean
@Conditional({ProCondition.class})
public DataBase proDataBase(){
return new DataBase("192.168.0.1","pro","222222");
}
@Bean
@Conditional(UatCondition.class)
public DataBase uatDataBase(){
return new DataBase("127.0.0.1","ron","111111");
}
}
如果在配置⽂件中,我们的env配置为UAT,则返回127.0.0.1的DataBase信息,env配置为Pro,则返回192.168.0.1的DataBase信息。
项⽬结构如下:
3、测试
创建单元测试ConditionTest,写⼊测试代码如下:
public class ConditionTest {
@Test
public void test() {
AnnotationConfigApplicationContext application = new AnnotationConfigApplicationContext(DataBaseConfig.class);
String[] names = BeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
DataBase dataBase = Bean(DataBase.class);
System.out.String());
}
}
当我们在配置⽂件写⼊如下内容
env=UAT
执⾏单元测试打印出的dataBase结果为:
DataBase [host=127.0.0.1,user=ron,password=111111]
当我们在配置⽂件写⼊如下内容
env=Pro
执⾏单元测试打印出的dataBase结果为:
DataBase [host=192.168.0.1,user=pro,password=222222]
⼩结:
本⽂我们通过实例的形式阐述了@Conditional的概念及应⽤,希望⼤家共勉。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。