如果某些bean注入是根据条件注入,而不是全部注入,我们就可以使用@Conditional注解,比如
当做bean的注入的时候不是系统启动全部注入,而是根据条件我想注入哪个bean,就注入哪个bean可以使用@Conditional注解
示例:当操作系统为windows系统我就注入一个bean为bill的person对象,当为linux操作系统时就注入一个bean为linus的person的对象。
那么咱先来写配置类
@Conditional注解里的类如果是WindowsCondition的条件类,就匹配当前这个bill的bean对象,
如果是LinuxCondition的条件类,就匹配linus的bean对象。
@Configuration
public class ConditionConfig {
/*
想要实现效果如果是windows,给容器中注册("bill")
想要实现效果如果是linus,给容器中注册("linus")
* */
@Conditional({WindowsCondition.class})
@Bean("bill")
public Person person01() {
return new Person("Bill Gates", 62);
}
@Conditional({LinuxCondition.class})
@Bean("linus")
public Person person02() {
return new Person("linus", 32);
}
}
来创建一个linux的条件类,并实现Condition接口
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;
import java.lang.annotation.Annotation;
// 判断是否是linux系统
public class LinuxCondition implements Condition {
/*
ConditionContext:判断条件能使用的上下文(环境)
AnnotatedTypeMetadata:注释信息
* */
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 获取当前环境信息
Environment environment = context.getEnvironment();
// 获取bean定义的注册类
BeanDefinitionRegistry registry = context.getRegistry();
// 获取操作系统名称
String name = environment.getProperty("os.name");
// 判断操作系统是linux返回true=匹配成功
if (name.contains("Linux")) {
return true;
}
return false;
}
}
来创建windows的条件类,并实现Condition接口
package springanntition.conditional;
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;
// 判断是否是windows系统
public class WindowsCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// TODO 想要查看是否Windows系统
// 能获取到IOC使用的beanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 获取类加载器
ClassLoader classLoader = context.getClassLoader();
// 获取当前环境信息
Environment environment = context.getEnvironment();
// 获取bean定义的注册类
BeanDefinitionRegistry registry = context.getRegistry();
// 获取操作系统名称
String name = environment.getProperty("os.name");
// 判断操作系统是Windows返回true=匹配成功
if (name.contains("Windows")) {
return true;
}
return false;
}
}
添加测试类main方法执行下看结果
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConditionConfig.class);
String[] namesForType = context.getBeanNamesForType(Person.class);
// 拿到系统运行环境
ConfigurableEnvironment environment = context.getEnvironment();
// 动态获取环境变量的值,os.name操作系统的名字
String property = environment.getProperty("os.name");
System.out.println(property);
for (String name : namesForType) {
System.out.println(name);
}
// 获取注入对象类型的map
Map<String, Person> beansOfType = context.getBeansOfType(Person.class);
System.out.println(beansOfType);
}
我测试的服务是windows系统的,所以经过匹配windows的要注入的bill对象,发现已经按照条件进行操作了。
如果是想要测试是否能够注入到linux的那个对象,需要修改下VM,添加-Dos.name=Linux
重新运行一下看结果,如果linux就会把linux系统对应的bean进行注入
以上就是@Conditional的使用