上篇文章:
Spring源码从入门到精通---@Scope&@Lazy(三)
大家是否都用过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系统情况下,才加载:
最后,看到这里的读者,喜欢的话安排一波(点赞,收藏,关注),原创不易,每周定期分享编程笔记。