@Conditional - 按条件注册bean
文章目录
英文学习:
- annotated : 注释
使用场景:
@Conditional注解是spring4.0的时候提出的注解, 使用在配置类的类上, 或者配置类中的@Bean注解修饰的方法上, 能达到的效果就是按照对应的条件来注册bean
- 使用到配置类上 : 满足当前条件, 这个类中配置的所有bean注册才能生效
- 使用到@Bean修饰的方法上 : 满足当前条件, 这个bean注册才能生效
@Conditional注解源码:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
/**
* All {@link Condition} classes that must {@linkplain Condition#matches match}
* in order for the component to be registered.
*/
Class<? extends Condition>[] value();
}
我们要传入一个Condition接口的实现类的class对象数组
@Conditional注解是一个根注解, 其下衍生了很多的注解, 在Spring底层使用到了很多的@Conditional注解以及@Conditional注解的衍生注解
1. 给出配置类
- 配置类中使用了两个条件装配:
package com.ffyc.spring.config;
import com.ffyc.spring.condition.LinuxCondition;
import com.ffyc.spring.condition.WindowsCondition;
import com.ffyc.spring.model.Person;
import org.springframework.context.annotation.*;
@Configuration
@ComponentScan(value = "com.ffyc.spring")
public class PersonConfig {
//如果程序运行的环境是windows操作系统, 就注册bill
@Bean("bill")
@Conditional( {
WindowsCondition.class
} )
public Person person01() {
return new Person(1,"bill");
}
//如果程序运行的环境是linux操作系统, 就注册linux
@Bean("linux")
@Conditional( {
LinuxCondition.class
} )
public Person person02() {
return new Person(1, "linux");
}
}
一个是如果符合WindowsCondition的条件, 那么就注册
一个是如果符合LinuxCondition的条件, 那么就注册
2.给出两个自定义条件类:
WindowsCondition:
package com.ffyc.spring.condition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class WindowsCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
ClassLoader classLoader = context.getClassLoader();
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
BeanDefinitionRegistry registry = context.getRegistry();
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.contains("Windows")) {
return true;
}
return false;
}
}
matches方法的参数:
- ConditionContext :
- 判断条件能使用的上下文(环境)
- AnnotatedTypeMetadata :
- 注释信息
通过条件能使用的上下文调用getClassLoader能获取到类加载器
通过条件能使用的上下文调用getBeanFactory方法能获取到IOC使用的bean工厂
通过条件能使用的上下文调用getRegister方法能获取到bean定义的注册类
通过条件能使用的上下文调用getEnvironment方法能获取到当前环境信息(JVM运行的各种环境信息)
LinuxCondition:
package com.ffyc.spring.condition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class LinuxCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
ClassLoader classLoader = context.getClassLoader();
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
BeanDefinitionRegistry registry = context.getRegistry();
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.contains("linux")) {
return true;
}
return false;
}
}
3.进行测试:
package com.ffyc.spring.test;
import com.ffyc.spring.config.PersonConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test4 {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(PersonConfig.class);
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for(String name : beanDefinitionNames) {
System.out.println(name);
}
}
}
由于是在window操作系统之下运行, 所以会创建bill对象
4.扩展测试:
启动程序的时候将JVM运行环境修改为linux操作系统
我们将JVM环境修改为linux操作系统之后, 然后进行一个测试, 我们就可以发现, 这个时候IOC容器中就注册(创建)了linux, 而没有创建bill