@Conditional注解详解

@Conditional注解详解本文我们要陈述的是如何根据不同的条件来判定到底注入那个 Bean 即 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 
  [] 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

(0)
上一篇 2026年3月18日 上午7:39
下一篇 2026年3月18日 上午7:39


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号