相关历史文章(阅读本文前,您可能需要先看下之前的系列)
国内最全的Spring Boot系列之四
享元模式:共享女友 - 第355篇
SpringBoot有没有学明白,就看你这些面试题是否懂?- 第389篇
Spring Boot CLI你知多少?- 第394篇
创建一个 Spring Boot 项目的4种方法,你会几种?- 第396篇
Spring Boot 项目中的 parent原来还有这么多的讲究 - 第398篇
师傅:在上一节咱们学习了
悟纤:师傅,这个一听就很深奥,徒儿还没有研究过呢。
师傅:今天咱们扒开源码以及一个小栗子来瞅瞅。
悟纤:师傅,那咱们赶紧扒呀…
师傅:说干就干… 话说…
Spring4中增加了@Condition annotation, 使用该Annotation之后,在做依赖注入的时候,会检测是否满足某个条件来决定是否注入某个类。
@ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)
@ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)
@ConditionalOnexpression(当表达式为true的时候,才会实例化一个Bean)
@ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)
@ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)
@ConditionalOnNotWebApplication(不是web应用)
具体我们还是看下源码对于上面的条件注解的使用:
一、JdbcTemplate
JdbcTemplate是我们在 *** 作DAO,很重要的一个类,我们在Spring Boot中添加如下依赖:
org.springframework.boot spring-boot-starter-jdbc
当我们添加了此依赖之后,并不需要进行什么配置就可以使用JdbcTemplate了。这就是Spring Boot进行的相应的一个配置,核心的配置类JdbcTemplateAutoConfiguration:
这个类上面有注解@Configuration和@import的注解:
(1)@Configuration:标记JdbcTemplateAutoConfiguration是配置类。
(2)@import导入其它的类。
具体的这个使用,可以看之前的文章《Spring Boot注解@import小试牛刀 - 第360篇》
Spring Boot注解@import小试牛刀 - 第360篇
@Configuration
@Configuration标记了JdbcTemplateAutoConfiguration类,那么此类就会被扫描到,那么这个类具体会不会被处理是有条件的,那么就是类上的条件注解了。
(1)@ConditionalOnClass({ DataSource.class, JdbcTemplate.class }):需要能够找到类DataSource和JdbcTemplate
(2)@ConditionalOnSingleCandidate(DataSource.class):Spring当前或父容器中必须存在DataSource这个类型的实例,且只有一个实例
@import
@import({ JdbcTemplateConfiguration.class, NamedParameterJdbcTemplateConfiguration.class })
中的@import会注入JdbcTemplateConfiguration和NamedParameterJdbcTemplateConfiguration,我们看下其中的一个:JdbcTemplateConfiguration,根据这个代码可以看到:
我们会看到在这里注入了JdbcTemplate。
二、其它一些小栗子说明
@ConditionalOnBean(javax.sql.DataSource.class)
Spring容器或者所有父容器中需要存在至少一个javax.sql.DataSource类的实例
@ConditionalOnClass({ Configuration.class,FreeMarkerConfigurationFactory.class })
类加载器中必须存在Configuration和FreeMarkerConfigurationFactory这两个类
@ConditionalOnexpression(“’${server.host}’==’localhost’”)
server.host配置项的值需要是localhost
@ConditionalOnJava(JavaVersion.EIGHT)
Java版本至少是8
@ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
Spring当前容器中不存在ErrorController类型的bean
@ConditionalOnMissingClass(“GenericObjectPool”)
类加载器中不能存在GenericObjectPool这个类
@ConditionalOnNotWebApplication
必须在非Web应用下才会生效
@ConditionalOnProperty(prefix = “spring.aop”, name = “auto”, havingValue = “true”, matchIfMissing = true)
应用程序的环境中必须有spring.aop.auto这项配置,且它的值是true或者环境中不存在spring.aop.auto配置(matchIfMissing为true)
@ConditionalOnResource(resources=”mybatis.xml”)
类加载路径中必须存在mybatis.xml文件
@ConditionalOnSingleCandidate(PlatformTransactionManager.class)
Spring当前或父容器中必须存在PlatformTransactionManager这个类型的实例,且只有一个实例
@ConditionalOnWebApplication
必须在Web应用下才会生效
三、我们要怎么使用?
这里我们举个小栗子说明下:
@ConditionalOnBean
要求bean存在时,才会创建这个bean;如我提供了一个bean名为RedisOperBean,用于封装redis相关的 *** 作;但是我这个bean需要依赖restTemplate这个bean,只有当应用引入了redis的相关依赖,并存在RestTemplate这个bean的时候,我这个bean才会生效
@Component @ConditionalOnBean(name="redisTemplate") public class RedisOperBean { private final RedisTemplate redisTemplate; public RedisOperBean(RedisTemplate redisTemplate) { // ... } }
这样的好处就是我提供的这个第三方包,如果被用户A间接依赖(但是A本身不需要 *** 作redis),也不会因为创建RedisOperBean而抛异常。
产生异常的原因是因为找不到RestTemplate的bean,因此无法实例化RedisOperBean,从而抛出异常。
我就是我,是颜色不一样的烟火。 我就是我,是与众不同的小苹果。
à悟空学院:悟空学院
学院中有Spring Boot相关的课程!!
SpringBoot视频:从零开始学Spring Boot Plus - 网易云课堂
SpringBoot交流平台:https://t.cn/R3QDhU0
SpringSecurity5.0视频:权限管理spring security - 网易云课堂
ShardingJDBC分库分表:分库分表Sharding-JDBC实战 - 网易云课堂
分布式事务解决方案:分布式事务解决方案「手写代码」 - 网易云课堂
JVM内存模型调优实战:深入理解JVM内存模型/调优实战 - 网易云课堂
Spring入门到精通:Spring零基础从入门到精通 - 网易云课堂
大话设计模式之爱你:大话设计模式之爱你一万年 - 网易云课堂
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)