在使用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
[] 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 org.springframework.core.type.AnnotationMetadata class} * or {@link org.springframework.core.type.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环境的数据库链接,如果配置的是生产环境,则返回生产环境的数据库链接。
首先是创建项目并添加必要的依赖,这里就不给出依赖配置的代码了,参考@ComponentScan向Spring IOC容器中注入组件。
在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 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 = context.getEnvironment(); if(env.getProperty("env").equals("UAT")){ return true; } return false; } } //生产环境的条件ProCondition public class ProCondition implements Condition { public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Environment env = context.getEnvironment(); if(env.getProperty("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",""); } @Bean @Conditional(UatCondition.class) public DataBase uatDataBase(){ return new DataBase("127.0.0.1","ron",""); } }
如果在配置文件中,我们的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 = application.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } DataBase dataBase = application.getBean(DataBase.class); System.out.println(dataBase.toString()); } }
当我们在配置文件写入如下内容
env=UAT
执行单元测试打印出的dataBase结果为:
DataBase [host=127.0.0.1,user=ron,password=]
当我们在配置文件写入如下内容
env=Pro
执行单元测试打印出的dataBase结果为:
DataBase [host=192.168.0.1,user=pro,password=]
小结:
本文我们通过实例的形式阐述了@Conditional的概念及应用,希望大家共勉。
代码参见:https://download.csdn.net/download/zyhlwzy/11181205
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/218274.html原文链接:https://javaforall.net
