Spring 注解之 Conditional 使用
前言
在Spring 中我们要是注册bean使用 @Bean @Component等注解执行在会像容器中注册Bean,但有的时候我们需要根据条件进行注册Bean,哪些需要注册到Ioc中,哪些不需要。
@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean。
注解详情
在 org.springframework.context.annotation;包下
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class<? extends Condition>[] value();
}
可以看到该注解可以指定在方法上也作用在类中。
可以看到传入参数可以传入多个类
代码示例
根据操作系统来指定像Ioc容器中注入那种Bean
分别创建 Persion1 和 Persion2 两个类
public class Persion1 {
private String namel;
public Persion1(String namel) {
this.namel = namel;
}
public String getNamel() {
return namel;
}
public void setNamel(String namel) {
this.namel = namel;
}
}
public class Persion2 {
private String namel;
public Persion2(String namel) {
this.namel = namel;
}
public String getNamel() {
return namel;
}
public void setNamel(String namel) {
this.namel = namel;
}
}
实现 Condition 接口 根据环境判断操作系统是Windows 还是 Linux
Condition 接口详情
public interface Condition {
boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
参数 ConditionContext var1
参数 AnnotatedTypeMetadata var2
ConditionContext 接口
public interface ConditionContext {
BeanDefinitionRegistry getRegistry();
ConfigurableListableBeanFactory getBeanFactory();
Environment getEnvironment();
ResourceLoader getResourceLoader();
ClassLoader getClassLoader();
}
接口方法说明
//1 获取环境
Environment environment = conditionContext.getEnvironment();
//2 获取类加载器
//ClassLoader classLoader = conditionContext.getClassLoader();
//3 获取ioc使用beanFactory
//ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
//4 获取bean定义的注册类 可以对bean进行操作
//BeanDefinitionRegistry registry = conditionContext.getRegistry();
编写对操作系统条件判断方法
public class ConditionalTest1 implements Condition {
//conditionContext 能使用的上下文环境
//annotatedTypeMetadata 注释信息
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//1 获取环境
Environment environment = conditionContext.getEnvironment();
//2 获取类加载器
//ClassLoader classLoader = conditionContext.getClassLoader();
//3 获取ioc使用beanFactory
//ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
//4 获取bean定义的注册类 可以对bean进行操作
//BeanDefinitionRegistry registry = conditionContext.getRegistry();
String property = environment.getProperty("os.name");
if (property.contains("Windows")) {
return true;
}
return false;
}
}
同理对Linux
public class ConditionalTest2 implements Condition {
//conditionContext 能使用的上下文环境
//annotatedTypeMetadata 注释信息
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
String property = environment.getProperty("os.name");
if (property.contains("Linux")) {
return true;
}
return false;
}
}
根据不同的操作系统注入不同的类
ConditionalTest1 注入windows
ConditionalTest2 注入linux
@Configuration
public class Concfigration {
@Bean
@Conditional(ConditionalTest1.class)
public Persion1 persion1(){
return new Persion1("windows");
}
@Bean
@Conditional(ConditionalTest2.class)
public Persion2 persion2(){
return new Persion2("linux");
}
}
测试
@Test
public void testEnviriment(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Concfigration.class);
//获取ioc当前系统环境
Environment environment = applicationContext.getEnvironment();
String property = environment.getProperty("os.name");
System.out.println(property);
if (property.contains("Windows")) {
Persion1 persion1 = applicationContext.getBean( Persion1.class);
System.out.println("persion1 = " + persion1);
}
if (property.contains("Linux")) {
System.out.println("linux");
Persion2 persion2 = applicationContext.getBean(Persion2.class);
System.out.println("persion1 = " + persion2);
}
}
}
Windows 下测试结果
Windows 7
persion1 = com.example.springdemo.conditional.Persion1@6b2e46af
Linux 下测试
可以在Linux下测试代码
也可以设置JVM参数 设置操作系统
linux
persion1 = com.example.springdemo.conditional.Persion2@88a8218
Conditional 注解在Spring Boot中大量使用
比如 Spring Boot中选择容器,根据条件查看类路径下是否有指定的包
可以看到注解
具体OnClassCondition 去判断类路径下是有相应的容器依赖。