@scheduled注解配置时间_「玩转SpringBoot」用好条件相关注解,开启自动配置之门...

v2-f89d6ef5e2facf7e1f62a2d5b93b6a2c_1440w.jpg?source=172ae18b

v2-6e1cba6ab92b8d565bf8a9dc59e5b968_b.jpg

封面图自动配置隐含两层含义,要搞清楚
上帝让程序员的发量减少,是为了让他变得更聪明,如果有一天聪明到了极点,那就是绝顶聪明。
据说在大脑高速运转下,这样更有利于散热,不至于核心温度过高而产生告警。
聪明的大脑是用来思考的,现在就来深入思考和分析下自动配置。
自动配置包含两层意思,一个是配置,一个是自动。这不废话嘛。
配置存在的一个前提是,要有选择才行,如果没得选择,就不用谈配置了。
比如十几年前读大学时,无论是回家还是去学校,都只能坐最便宜的硬座。因为没得选择。
现在情况就不一样了,高铁、动车、飞机都可以了。有了选择,就可以谈配置了。
所以配置就是在一些可选项里做出选择,既然是选择,就需要有选择的依据/理由。
如果距离不太远的话,选择高铁,这样在花费的时间和金钱上是相对均衡的。
如果此时想稍微省点钱的话,选择动车,不过花的时间稍多些。也算一种取舍吧。
如果距离太远的话,选择飞机,这样时间和金钱上才是最均衡的。
这些列举出来的影响选择的因素,其实就是“条件”。因此,配置就是根据条件做出选择。
那自动的意思就是,使用工具或一套程序根据条件做出选择,最后只把结果告诉我们即可。
就是说,我们不参与选择的过程,我们只需提供一些和“条件”相关的信息即可。Spring的风格,万物皆可注解
通过上一小节,我们成功的把自动配置转化为条件和工具。
回到程序里,条件指的是什么?如果不知道的话,那条件语句指的是什么?
就是if...else,要根据条件做出判断,所以条件就是某种形式的程序代码。
那工具呢?就是一些常用代码或算法的集合嘛。也是某种形式的程序代码。
条件和工具已经被成功的转化为了程序代码,现在来看,自动配置就等于程序代码。
关键是这个程序代码是让我们来写吗?如果是的话,那可就产生悖论了。
因为配置通常意味着不写代码,如果还要写代码的话,那就不叫配置了,叫搞笑了。
因此,条件和工具的程序代码,SpringBoot都写好了,并通过注解进行了封装。
最后把这些注解暴露出来,供用户使用,这就是条件注解的由来。
用户可以通过设置注解属性把“条件”相关信息传递进去,让底层的“工具”进行判断和选择。
最终,不同的条件产生了不同的行为,达到了自动配置的目的。官方提供的常用条件注解
因为Spring的核心是基于bean的,所以这些条件注解主要是影响bean的注册。
因为注册的bean不同了,最后对外呈现的行为就不同了。不就是自动配置了。
一、最常用的应该是@Profile注解了
根据不同的环境可以注册不同的bean,如下图01:

v2-7b5b73baa16e3d9a56f721d813983408_b.jpg


首先,不激活任何环境,执行一下,结果如下图02:

v2-b7f7e31d55c5cf41ba7a99ec50b5f8e8_b.jpg


可以看到,没有激活任何环境,所以默认是default。因此Default类就被注册了。
然后,激活一下prod环境,在IDE里设置一下,如下图03:

v2-19c7255249276f57a729dd85f94f0494_b.jpg


再次运行一下,结果如下图04:

v2-17693f998ca5173c8a66be43e8502f0f_b.jpg


可以看到,prod环境被激活了,所以Prod类就被注册了。
SpringBoot内置了一些注解,如下图05:

v2-3afd63e61bb96c88d704c3696a6974d1_b.jpg


我们关注一些常用的就可以了。
二、@ConditionalOnProperty注解
这个注解用于检测Environment中的指定属性是否存在或等于某个指定的值。
如下图06:

v2-819b053e7b5b20e898bcdf4464f798ac_b.jpg


如havingValue属性没有指定的话,那么只要实际属性值不等于false,都算匹配成功。如果指定了,那就必须要一样才行。
matchIfMissing属性就是说,如果没有发现这个属性,算不算匹配上,设置为true就算,false就不算,默认为不算。
请看配置文件,如下图07:

v2-15425fb41c33eb605be7da18c74394fb_b.jpg


很明显,这是可以匹配上的,运行一下,结果如下图08:

v2-ddd32e1c81c98a47fe1f4ca8e2955328_b.jpg


可以看到,对应的类被注册了bean定义。
三、@ConditionalOnClass注解
这个注解用于检测类路径里是否包含某个类,其实就是确定是否引入了指定的依赖。
如下图09:

v2-7f1d3edb941d7abe8b4ccafa9670e79b_b.jpg


因为我用的JDK1.8,肯定有这个类,所以会匹配上,结果如下图10:

v2-04e3a1da3d068ffeae48cef6301fe1dd_b.jpg

:@ConditionalOnMissingClass注解原理一样,只不过是否定性的匹配而已。
四、@ConditionalOnBean注解
这个注解用于检测容器中是否包含指定的bean。如下图11:

v2-25692dd99179fa989a1b72a53d59d0a0_b.jpg


除了可以用Class<?>指定bean外,还可以使用类的全名称,还可以使用bean名称(即beanName)。
还可以使用注解指定是否包含标有该注解的bean。
示例中是通过Class<?>来指定的,而且指定的是之前注册过的bean,所以一定能匹配上。
执行结果如下图12:

v2-c8ba8256ce09972bc9bcf3b0dba77efd_b.jpg

:@ConditionalOnMissingBean注解原理一样,只不过是否定性的匹配而已。
五、@ConditionalOnSingleCandidate注解
这个注解用于检测容器中能够匹配上的候选bean是否只有一个。
只有一个是什么意思呢?就是某个类只注册了一次,这时就是只有一个。比如Boss类。
但是员工可以有多个,所以就会有多个Staff类被注册。此时就不满足条件了。
如果此时还想满足的话,就必须在其中一个Staff类注册时标上@Primary注解。
如下图13:

v2-1d21dec36a875bd8817852e517cc83ee_b.jpg


因为我们指定的bean只注册了一次,所以一定满足条件。
执行结果如下图14:

v2-e7f77c7bd8902f0286b760071f6a960a_b.jpg


六、@ConditionalOnResource注解
这个注解用于检测类路径中是否包含指定的资源。一般也就是文件了。
我们来检测下配置文件,如下图15:

v2-e3e6a3ce476922a583aee41c65f35c5d_b.jpg


肯定是存在的,执行结果如下图16:

v2-295864be1c1264b7ccebc4be4c3f04d2_b.jpg

自定义条件注解
需要实现一个条件接口,如下图17:

v2-8aa6ed5679be4252ef59ea7f6dbb39f4_b.jpg


只有一个方法,返回true表示匹配上,false则相反。
方法的第一个参数,是一个上下文,如下图18:

v2-3e7cb5b11db1dd3f66e0cc18c1b06e63_b.jpg


这里有很多的东西供我们使用。
方法的第二个参数,是最终标有我们定义好的条件注解的那个类,这个一定要明白。
我们来定义两个和操作系统对应的注解,一个用于Windows,一个用于Linux。
Windows版本的实现,如下图19:

v2-568c3099d431818662bdadde5f827b5a_b.jpg


从Environment中读出操作系统的名称,看是否包含windows即可。
Linux版本的实现,如下图20:

v2-61e919028e823451c08add39bfa17241_b.jpg


原理和刚刚的一样。
再定义两个注解,分别和这两个条件实现类关联起来。
Windows版本的,如下图21

v2-09142d975e83044f49fb63d8af7fade7_b.jpg


Linux版本的,如下图22:

v2-d05316ca951111fe068f5d79fc7d7361_b.jpg


然后开始试用一下这两个条件注解,如下图23:

v2-fc8cb519bc17b3aa571658f0a8c4a0e1_b.jpg


因为我用的是Windows,所以肯定只有@Windows注解可以匹配。
执行结果如下图24:

v2-569519f0687f68c6b61dec3447b7ae0e_b.jpg


这只是一个简单的示例,可以根据自己的需要定义更加复杂的,但是原理和流程都是一样的。>>> 玩转SpringBoot系列文章 <<<
【玩转SpringBoot】配置文件yml的正确打开姿势>>> 品Spring系列文章 <<<
品Spring:帝国的基石
品Spring:bean定义上梁山
品Spring:实现bean定义时采用的“先进生产力”
品Spring:注解终于“成功上位”
品Spring:能工巧匠们对注解的“加持”
品Spring:SpringBoot和Spring到底有没有本质的不同?
品Spring:负责bean定义注册的两个“排头兵”
品Spring:SpringBoot轻松取胜bean定义注册的“第一阶段”
品Spring:SpringBoot发起bean定义注册的“二次攻坚战”
品Spring:注解之王@Configuration和它的一众“小弟们”
品Spring:bean工厂后处理器的调用规则
品Spring:详细解说bean后处理器
品Spring:对@PostConstruct和@PreDestroy注解的处理方法
品Spring:对@Resource注解的处理方法
品Spring:对@Autowired和@Value注解的处理方法
品Spring:真没想到,三十步才能完成一个bean实例的创建
品Spring:关于@Scheduled定时任务的思考与探索,结果尴尬了>>> 热门文章集锦 <<<
毕业10年,我有话说
【面试】我是如何面试别人List相关知识的,深度有点长文
我是如何在毕业不久只用1年就升为开发组长的
爸爸又给Spring MVC生了个弟弟叫Spring WebFlux
【面试】我是如何在面试别人Spring事务时“套路”对方的
【面试】Spring事务面试考点吐血整理(建议珍藏)
【面试】我是如何在面试别人Redis相关知识时“软怼”他的
【面试】吃透了这些Redis知识点,面试官一定觉得你很NB(干货 | 建议珍藏)
【面试】如果你这样回答“什么是线程安全”,面试官都会对你刮目相看(建议珍藏)
【面试】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)
【面试】一篇文章帮你彻底搞清楚“I/O多路复用”和“异步I/O”的前世今生(深度好文,建议珍藏)
【面试】如果把线程当作一个人来对待,所有问题都瞬间明白了
Java多线程通关———基础知识挑战
品Spring:帝国的基石作者是工作超过10年的码农,现在任架构师。喜欢研究技术,崇尚简单快乐。追求以通俗易懂的语言解说技术,希望所有的读者都能看懂并记住。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值