005Spring注解@Conditional
1、简介
@Conditional按照一定的条件进行判断,满足条件给容器中注册bean。
2、基础类
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
3、@Conditional
3.1、取值
Condition[]
3.2、作用域
可以作用到类上也可以作用到方法上。
3.3、讲解
3.3.1、概述
@Conditional按照一定的条件进行判断,满足条件给容器中注册bean。SpringBoot底层大量运用了此注解。
3.3.2、需求一
判断当前系统是windows还是linux,若是windows则注册一个bean的id为bill的bean,若是linux系统则注册一个bean的id为linus的bean。
3.3.3、配置类
@Configuration
public class MainConfig {
/**
* @Conditional({Condition}): 按照一定的条件进行判断,满足条件给容器中注册bean
*
* 若是windows系统,则给容器中注册bill
* 若是linux系统,则给容器中注册linux
*
* @return
*/
@Bean("bill")
@Conditional({WindowsCondition.class})
public User user01() {
return new User("比尔盖茨", 62);
}
@Bean("linus")
@Conditional({LinuxCondition.class})
public User user02() {
return new User("Linux", 45);
}
}
3.3.4、WindowsCondition
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 获取当前环境信息
Environment environment = context.getEnvironment();
String osname = environment.getProperty("os.name");
if (osname.contains("Windows")) {
return true;
}
return false;
}
}
3.3.5、LinuxCondition
public class LinuxCondition implements Condition {
/**
* ConditionContext:判断条件能使用的上下文(环境)
* AnnotatedTypeMetadata:注释信息
*
* @param context: 判断条件能使用的上下文(环境)
* @param metadata: 注释信息
* @return
*/
@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();
String osname = environment.getProperty("os.name");
if (osname.contains("Linux")) {
return true;
}
return false;
}
}
3.3.6、概括
-
我们发现@Conditional的源码的value值需要一个Condition的数组
Class<? extends Condition>[] value();
所以大概格式为:
@Conditional({Condition.class})
-
自定义Condition条件需要实现Condition接口,并重写matches方法。
-
matches方法的参数可以获取当前环境信息、bean的注册情况等等,这些都可以作为判断的条件。
比如我们上面获取了os.name,然后判断是Linux还是Windows。
再比如我们还可以用registry.containsBeanDefinition(beanName)来判断是否包含某个bean,若包含则加载当前bean,否则不加载等等。
3.3.7、测试类
public class ConditionalTest {
private ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
@Test
public void test() {
String[] names = applicationContext.getBeanNamesForType(User.class);
for(String name : names) {
System.out.println(name);
}
Map<String, User> beans = applicationContext.getBeansOfType(User.class);
System.out.println(beans);
}
}
3.3.8、测试结果
bill
{bill=User{name='比尔盖茨', age=62}}
PS:
结果分析:
因为我是Windows 10的系统,所以打印了bill,和bill的bean信息。linus的没有打印。
3.3.9、修改环境是Linux
3.3.9.1、修改方法
在VM options里写-Dos.name=Linux
3.3.9.2、测试结果
linus
{linus=User{name='Linus', age=45}}
3.3.10、补充
我们看到我们的测试例子是将注解写到方法上的,我们也可以将@Conditional注解定义到类上,定义到类上代表若不符合条件,则整个类都不会加载。
4、广告
-
码云点star,万分感谢!
代码已经上传到码云了
https://gitee.com/geekerdream/spring-anonation
通用的权限处理框架
https://gitee.com/geekerdream/common-security
通用的异常处理
https://gitee.com/geekerdream/exception-handler
通用的发送邮件
https://gitee.com/geekerdream/common-boot-email
陆续会推出更多干货,希望关注!
-
QQ群【Java初学者学习交流群】:458430385
-
微信公众号【Java码农社区】
![](https://img.haomeiwen.com/i4582242/ca4a357ae859b1aa.jpg)
- 今日头条号:编程界的小学生