@Conditional-根据条件是否注册bean
@Conditional 有很多子注解,简单写两个
这些注解可以标注在方法或者类上
@ConditionalOnBean
当容器中有指定的bean是注册到容器中
@ConditionalOnMissingBean
当容器中没有指定的bean是注册到容器中
@ConditionalOnClass
当容器中有指定类时注册到容器中
@ConditionalOnMissingClass
当容器中没有指定类时注册到容器中
@ConditionalOnResource
当类路径中存在某个资源时注册到容器中
@ConditionalOnJava
当指定某一个java版本时注册到容器中
@ConditionalOnWebApplication
当我们应用是一个Web应用时注册到容器中
@ConditionalOnNotWebApplication
当我们应用不是一个Web应用时注册到容器中
第一种配置(主程序类执行@SpringBootApplication)
配置类
// 因为是@SpringBootApplication主程序类执行不是测试类执行所以没有写@Configuration @Component public class MyConfig { @Bean public User user(){ return new User("张三",10); } @Bean @ConditionalOnBean(User.class) public Info info(){ return new Info("长春","男"); } }
@Data public class User { private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } }
@Data public class Info { private String address; private String sex; public Info(String address, String sex) { this.address = address; this.sex = sex; } }
输出类
@SpringBootApplication public class StudyWork1Application { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(StudyWork1Application.class, args); String[] names = run.getBeanNamesForType(User.class); for (String name : names) { System.out.println("user类型:"+name); } String[] names1 = run.getBeanNamesForType(Info.class); for (String s : names1) { System.out.println("info类型:"+s); } } }
数据结果
测试不注册User,把注册User的@Bean去掉在输出,发现没有了info
第二种配置(测试类执行@Test)
配置类
// 配置类注解 告诉spring这是个配置 @Configuration public class MyConfig { /** * @Conditional({Condition}) : 按照一定的条件进行判断,满足条件给容器中注册bean * * 如果系统是windows,给容器中注册("configNameWin") * 如果是linux系统,给容器中注册("configNameLinux") */ @Conditional(MyWinCondition.class) @Bean public Pet configNameWin(){ System.out.println("Win中configName配加载了。。。。。。"); return new Pet("小猫Win",2); } @Conditional(MyLinuxCondition.class) @Bean public Pet configNameLinux(){ System.out.println("Linux中configName配加载了。。。。。。"); return new Pet("小猫Linux",2); } }
MyWinCondition 实现Condition接口 重写matches方法 在方法中判断是否注册bean
public class MyWinCondition implements Condition { /** * ConditionContext:判断条件能使用的上下文(环境) * AnnotatedTypeMetadata:注释信息 */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //1、能获取到ioc使用的beanfactory ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); //2、获取类加载器 ClassLoader classLoader = context.getClassLoader(); //3、获取当前环境信息 Environment environment = context.getEnvironment(); //4、获取到bean定义的注册类 BeanDefinitionRegistry registry = context.getRegistry(); //可以判断容器中的bean注册情况,也可以给容器中注册bean boolean definition = registry.containsBeanDefinition("person"); // 获取系统名称 String property = environment.getProperty("os.name"); if(property.contains("Windows")){ return true; } return false; } }
MyLinuxCondition 实现Condition接口 重写matches方法 在方法中判断是否注册bean
public class MyLinuxCondition implements Condition { /** * ConditionContext:判断条件能使用的上下文(环境) * AnnotatedTypeMetadata:注释信息 */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //1、能获取到ioc使用的beanfactory ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); //2、获取类加载器 ClassLoader classLoader = context.getClassLoader(); //3、获取当前环境信息 Environment environment = context.getEnvironment(); //4、获取到bean定义的注册类 BeanDefinitionRegistry registry = context.getRegistry(); //可以判断容器中的bean注册情况,也可以给容器中注册bean boolean definition = registry.containsBeanDefinition("person"); // 获取系统名称 String property = environment.getProperty("os.name"); if(property.contains("linux")){ return true; } return false; } }
win系统输出
@Test public void test1() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class); String[] beanNamesForType = applicationContext.getBeanNamesForType(Pet.class); for (String name:beanNamesForType) { System.out.println(name); } }
win系统输出结果
linux系统输出
@Test public void test1() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class); String[] beanNamesForType = applicationContext.getBeanNamesForType(Pet.class); for (String name:beanNamesForType) { System.out.println(name); } }
linux系统输出结果
idea 配置模拟linux
打开idea中edit configurations 根据下图红框提示填入
-Dos.name=linux