该系列文章主要学习 雷丰阳老师的《Spring注解驱动》课程总结。
原课程地址:课程地址包括了自己阅读其他书籍《Spring揭秘》《Spring Boot 实战》等课程。
该系列文档会不断的完善,欢迎大家留言及提意见。
Spring支持按照条件向 IOC 容器中注册 bean ,满足条件的 bean 就会被注册到 IOC 容器中,不满足条件的 bean 就不会被注册到 IOC 容器中。接下来,我们就一起来探讨一下 Spring 中是如何实现按照条件向 IOC 容器中注册 bean 的。
查看该注解源码,发现 value 是一个必须要实现 Condition 的类,该类就是用于判断是否能够注入 Bean。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
/**
* All {@link Condition}s that must {@linkplain Condition#matches match}
* in order for the component to be registered.
*/
Class<? extends Condition>[] value();
}
Condition 类本身是一个接口,只提供了一个 match 方法,用于判断是否应该注入 bean
public interface Condition {
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
1. 编写自定义的 Condition 实现类
如果当前系统是 mac 系统则不注入 Bean。
要想使用@Conditional注解,我们需要实现Condition接口来为@Conditional注解设置条件,所以,这里需要定义自己的 Condition 实现类。
定义 condition
public class MacCondition implements Condition {
private static final String MAC = "Mac OS X";
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 获取当前环境信息,它里面就封装了我们这个当前运行时的一些信息,包括环境变量,以及包括虚拟机的一些变量
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if (!property.contains(MAC)) {
return true;
}
return false;
}
}
将 bean 注入进去
@Configuration(value = "mainConfig")
@Conditional(value = MacCondition.class)
public class MainConfig {
@Bean(value = "boy")
public Person personBoy() {
System.out.println("boy……如果这句话在启动的时候打印,表示启动时生成的……");
return new Person("张三", 20);
}
查看当前容器中所有的 Bean
public class TestMain {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
printAllBean(applicationContext);
}
private static void printAllBean(ApplicationContext applicationContext) {
System.out.println("=====所有的Bean对象=====");
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String s : beanDefinitionNames) {
System.out.println(s);
}
}
}
打印所有的 bean 对象,发现 MainConfig 和 Bean 组件没有输出
=====所有的Bean对象=====
// 只是打印了系统的组件
如果移除 @Conditional(value = MacCondition.class)
注解,则可以看到 自定义的 Bean
boy……如果这句话在启动的时候打印,表示启动时生成的……
=====所有的Bean对象=====
// 系统自带的 bean
mainConfig
boy