@Conditional 是 Spring 4.0 提供的新注解。条件注解,顾名思义就是根据不同的条件加载不同的 Bean 到容器中。条件是写在一个接口实现类中,该条件所在的方法会返回布尔类型值,true 的时候表示满足该条件。
Conditional 的定义如下:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Conditional {
/**
* All {@link Condition}s that must {@linkplain Condition#matches match}
* in order for the component to be registered.
*/
Class<? extends Condition>[] value();
}
可以看到,这个注解用于方法或者类。并且其中的 value 就是一个 condition 接口类型。condition 接口的定义如下:
Condition接口
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 registration.
*/
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
当 condition 接口的 matches 方法满足的情况下,标注的 Bean 就可以加载。
下面演示一下用法,当环境是 dev 的时候,返回 dev 的 DataSource,环境是 prd 的时候,返回 prd 的 DataSource。
演示
新建如下几个文件
DataSource类
package com.learn.entity;
public class DataSource {
private String dataSourceName;
public String getDataSourceName() {
return dataSourceName;
}
public void setDataSourceName(String dataSourceName) {
this.dataSourceName = dataSourceName;
}
}
配置类
package com.learn;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import com.learn.condition.DevDataSourceCondition;
import com.learn.condition.ProdDataSourceCondition;
import com.learn.entity.DataSource;
@Configuration
public class Config {
@Bean(name="DataSource")
@Conditional(DevDataSourceCondition.class)//条件注解,满足该条件就会加载这个类到容器中
public DataSource devDataSource()
{
DataSource d=new DataSource();
d.setDataSourceName("dev");
return d;
}
@Bean(name="DataSource")
@Conditional(ProdDataSourceCondition.class)//条件注解,满足该条件就会加载这个类到容器中
public DataSource prdDataSource()
{
DataSource d=new DataSource();
d.setDataSourceName("prd");
return d;
}
}
条件接口的实现类。 DevDataSourceCondition
package com.learn.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class DevDataSourceCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String env = context.getEnvironment().getProperty("application.env");
return env.equalsIgnoreCase("dev");
}
}
ProdDataSourceCondition
package com.learn.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class ProdDataSourceCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String env = context.getEnvironment().getProperty("application.env");
return env.equalsIgnoreCase("pro");
}
}
入口类,Main 方法
package com.learn;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.learn.entity.DataSource;
public class Main {
public static void main(String[] args) {
//使用Config.class这个配置类
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
System.out.println("实例个数:" + applicationContext.getBeanDefinitionCount());
//遍历容器中的所有的实例的名字
for (String n : applicationContext.getBeanDefinitionNames()) {
System.out.println(n);
}
//根据类型获取实例
DataSource ds= applicationContext.getBean(DataSource.class);
System.out.println("实例名字:" +ds.getDataSourceName());
applicationContext.close();
}
}
运行的时候,需要配置虚拟机参数,便于测试:
可以运行结果如下:
实例个数:10 org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalRequiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory config org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor DataSource 实例名字:prd