上篇文章:
@Scope&@Lazy---Spring源码从入门到精通(三)
大家是否都用过System.getProperties.getPropertite(“os.name”),获取过登入系统,这篇文章就看Conditional注解源码,如何获取系统信息。
@Conditional作用只有一个实例会给ComponentScan扫描(好多文章说的是只有一个实例给容器管理,我的理解是不对的,ComponentScan扫描之后才给容器,如果被过滤了,容器里面就没有)。所以他在ComponentScan过滤之前进行。
从conditional源码里可以看到,制定了两个elementType,可以放在方法上,也可以放在类上。先放目录,这篇文章主要新增两个condition类
1、Conditional放在方法上
先写两个bean,一个mac,一个Linux,然后定义macConditional和linuxCondition代码如下。
/** * * @author keying */ @Configuration //满足conditional条件,这个类的配置信息才可以生效 //@Conditional({LinuxCondition.class}) public class BeanConfig2 { @Scope @Lazy @Bean(value = "person") public Person getPerson(){ System.out.println("把bean交给容器管理"); return new Person("person2",19); } /** * @Conditional判断条件,满足就放入容器 * */ @Bean(value = "Mac") @Conditional({MacCondition.class}) public Person getMac(){ return new Person("Mac",1); } @Bean(value = "Linux") @Conditional({LinuxCondition.class}) public Person getLinux(){ return new Person("Linux",2); } }
写两个condition,下面是判断mac的示例:
/** * 判断mac * * @author keying * @date 2021/6/27 */ public class MacCondition implements Condition { /** * * @param context 判断条件使用的上下文 * @param metadata 注释信息 * @return */ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //1、ioc使用的bean工厂 ConfigurableListableBeanFactory configurableListableBeanFactory = context.getBeanFactory(); //2、类的加载器 ClassLoader classLoader = context.getClassLoader(); //3、环境 Environment environment = context.getEnvironment(); //4、定义bean BeanDefinitionRegistry beanDefinitionRegistry = context.getRegistry(); String name = environment.getProperty("os.name"); if(name.contains("Mac")){ return true; } return false; } }
最后执行junit测试:
@org.junit.Test public void test3(){ /* String[] beanNames = annotationConfigApplicationContext.getBeanDefinitionNames(); for (String beanName : beanNames) { System.out.println(beanName); }*/ String[] names = annotationConfigApplicationContext.getBeanNamesForType(Person.class); System.out.println("==========="); for (String name : names) { System.out.println(name); } Map<String,Person> map = annotationConfigApplicationContext.getBeansOfType(Person.class); System.out.println(map); /* ConfigurableEnvironment configurableEnvironment = annotationConfigApplicationContext.getEnvironment(); String name = configurableEnvironment.getProperty("os.name"); System.out.println(name);*/ }
输出的结果可以看到,linux系统的并没有打印出来,而mac的就打印出来了。
2、Conditional放在类上
/** * * @author keying */ @Configuration //满足conditional条件,这个类的配置信息才可以生效 @Conditional({LinuxCondition.class}) public class BeanConfig2 { @Scope @Lazy @Bean(value = "person") public Person getPerson(){ System.out.println("把bean交给容器管理"); return new Person("person2",19); } /** * @Conditional判断条件,满足就放入容器 * */ @Bean(value = "Mac") @Conditional({MacCondition.class}) public Person getMac(){ return new Person("Mac",1); } @Bean(value = "Linux") public Person getLinux(){ return new Person("Linux",2); } }
当放在类上在执行可以看到,结果打印的是空的,因为当前类只能在linux系统情况下,才加载: