目录
分析
通过获取 run() 的返回值再获取容器中的bean
@Conditional() 注解
解说案例
1.导入Jedis坐标后,加载该Bean,没导入,则不加载
思考
spring-boot-autoconfigure
condition包
ConditionalOnClass
ConditionalOnBean
ConditionalOnMissingBean
ConditionalOnProperty
data 包
2.将类的判断定义为动态的;判断哪个字节码文件存在可以动态指定
小结
- Condition 是在 Spring 4.0 增加的条件判断功能
- 通过这个功能可以实现选择性的创建 Bean 操作
-
分析
- 进入 SpringBoot 启动类,点击进入 run()
- 可以看到这个方法是有返回值的,返回值为 ConfigurableApplicationContext
- 这个返回值就是 IOC 容器
-
通过获取 run() 的返回值再获取容器中的bean
- 首先在 pom.xml 中导入 Redis 的起步依赖
- 在启动类中编写获取 redisTemplate 代码
-
@Conditional() 注解
- Spring 在创建 Bean 时,可以在方法上添加条件注解 @Conditional()
- 里面 Condition 就是核心的条件接口
- 接口中只有一个 matches() 方法,返回值为 boolean 类型
- 所以要使用 @Conditional() 注解就需要在注解中传入一个 Condition 条件接口的实现类
- 并且实现类要复写 matches() ,返回 true 或者 false
- 如果返回的是 true,那么对应的 Bean 将会被 Spring 容器创建
- 如果返回的是 false,那么容器则不会创建对应的 Bean
-
解说案例
- 在Spring的IOC容器中有一个User的Bean,现要求:
-
1.导入Jedis坐标后,加载该Bean,没导入,则不加载
- 如果把 pom.xml 文件中的 Jedis 坐标注释掉
- 那么Spring 容器则不会创建 User 对应的 Bean,运行启动类就获取不到 user 对象
-
思考
- 根据之前在启动类中编写的获取redisTemplate 的代码
- SpringBoot 是如何知道要创建RedisTemplate 的?
- 其实 SpringBoot 就是使用 Condition 去判断当前环境中有没有导入 Redis 的 start,如果导入了,那么就会创建 RedisTemplate
-
spring-boot-autoconfigure
- 在 SpringBoot 中提供了非常多的 ConditionalOn* 的类
- 可以在 External Libraries 中找到 spring-boot-autoconfigure 这个 SpringBoot 的自动配置 jar 包
- 其中有一个 condition 包,可以看到这个包里有很多 ConditionalOn*
-
condition包
- 拿几个讲下
-
ConditionalOnClass
- 进入 ConditionalOnClass 中可以看到,他里面定义了一个注解
- 注解上面有一个 @Conditional,value 值为 OnClassCondition.class
- 这个操作就是在判断是否有对应的字节码文件
-
ConditionalOnBean
- 当 IOC 容器中有指定 Bean 的时候,才会去初始化指定的 Bean
-
ConditionalOnMissingBean
- 当 IOC 容器中没有指定 Bean 的时候,才会去初始化指定的 Bean
-
ConditionalOnProperty
- 当配置文件中配置了指定的属性,才会创建某一个 Bean
-
data 包
- data 包中有一个 redis 的包
- redis 有一个配置类为 RedisAutoConfiguration,如图可以看到这个配置类在初始化 RedisTemplate
- 并且有一些初始化的条件:
- @ConditionalOnClass(RedisOperations.class)
- 在当前环境中需要有 RedisOperations 字节码存在,才能去创建下面方法的 Bean
- (因为这个注解是加在类上的,所以下面所有的方法都要满足这个条件才可以创建 Bean)
- @ConditionalOnMissingBean(name = “redisTemplate”)
- 可以看到在 redisTemplate 方法上添加了一个这样的注解
- 它代表如果当前环境中不存在 redisTemplate,才会创建 RedisTemplate
- 如果存在,那就证明我们自己定义了 RedisTemplate,则不会创建
-
2.将类的判断定义为动态的;判断哪个字节码文件存在可以动态指定
- 去自定义一个注解来实现动态导入指定值判断是否创建Bean
-
小结
- 介绍了来由与自定义的条件以及 SpringBoot 提供的常用条件注解
- 自定义条件
- 1.定义条件类:
- 自定义类实现 Condition 接口,重写 matches 方法
- 在 matches 方法中进行逻辑判断,返回 boolean 值
- matches 方法两个参数:
- context:上下文对象,可以获取属性值、类加载器、BeanFactory 等
- metadata:元数据对象,用于获取注解属性
- 2.判断条件:在初始化 Bean 时,使用 @Conditional(条件类.class) 注解
- SpringBoot 提供的常用条件注解
- ConditionalOnProperty:判断配置文件是否有对应的属性和值才初始化 Bean
- ConditionalOnClass:判断环境中是否有对应的字节码文件才初始化 Bean
- ConditionalOnMissingBean:判断环境中没有对应 Bean 才初始化 Bean