详解Spring Boot 自动配置机制

转载本文需注明出处:微信公众号EAWorld,违者必究。



一、简介



Spring boot 是一个基于 Spring框架开发,高于 Spring 框架,它对 Spring 做了更好的封装,提供了更多的产品级特性,极大的提升了 Spring 的可用性。


Spring 的配置一直都是诟病,直到 Java Config 推出之后,得到了很大的改善,但Java Config 也存在很多问题,例如:开发人员往往找不到配置到底在哪!


Spring Boot 统一了配置模式(application.yml),并且提供了很多的默认配置,让我们可以有更多的时间关注业务逻辑;当需要进行扩展或者进行修改的时,又不失灵活性。


二、Spring Boot 自动配置


Spring Boot 自动配置的目标是通过 jar 包的依赖,自动配置应用程序。



做到这一点,Spring Boot 使用了一个很多人都不知道的类:SpringFactoriesLoader



SpringFactoriesLoader 是一个抽象类,他会通过loadFactories/loadFactoryNames加载每个 jar 包中META-INF/spring.factories文件。


spring.factories如上图所示,该文件是spring-boot-autoconfigure-1.5.8.RELEASE.jar包中META-INF/spring.factories的内容,其实就是一个属性文件,左侧通常为一个接口或者是一个注解类,右侧为接口的实现,或者是和左值相关的注解。


Spring Boot 自动配置就是加载spring.factories中EnableAutoConfiguration下配置的所有的配置源,并注册到 Spring 的 ApplicationContext 上去,了解了这个机制后,我们就可以按照自己的需求定制自动配置。


在我们的 EOS8 微服务平台中,我们就使用到这种配置方式:


三、Spring Boot 自带自动配置


Spring Boot 的自动配置模块spring-boot-autoconfigure,几乎提供了我们常见Spring 整合框架的所有的自动配置功能,例如:database、JPA、security、session 等等;


在官网上可以找到一个列表,我们可以去方便的查看,按照项目需求进行使用:

https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/#auto-configuration-classes-from-autoconfigure-module


当然,我们也可以找到对应的配置类,以方便我们可以更好的了解配置项。


四、Condition和@Conditional


Spring Boot 的autoconfigure机会囊括了所有的可以和Spring 整合的项目,这样做的最大好处是,我们不用再去为版本的兼容性而烦恼,只要按照官方推荐的版本,加入依赖的 jar 就可以;


但通常情况下,这么多的功能,并不是都需要,Spring Boot 灵活的使用 Spring 的条件配置,让 Spring Boot 的自动配置,只有在满足指定条件的情况下才会生效。


通常情况下,判断条件有如下几种情况:


  • 判断 classpath 中是否存在指定的类

  • 判断 ApplicationContext 中是否存在指定的 Bean

  • 配置环境中是否存在特定的配置项

  • 配置环境中指定的配置项是否存在指定的值


当然,我们也可以通过自定义Condition接口的实现,使用@Conditional注解指定;

Spring Boot 中自定义了很多的条件注解类:


通过这些注解的名称,我们就很容易知道他们的含义。


五、禁用默认配置


如果我们不想使用默认的配置,但是默认的配置又满足启用的条件,应用启动的时候,配置也生效,这个时候,我们可以通过下面的方式来禁用默认配置:



或者,直接这样:


六、Spring Boot 配置源的加载


Spring Boot加载配置源是以 Spring 为基础的; 适用于 Spring 的配置源,均适用于 Spring Boot,如:xml、groovy、java config 等。


Spring 在启动 ApplicationContext 的时候,需要明确指定启动的配置文件或者配置类;

Spring Boot 是在启动 SpringApplication 之前,预先配置环境资源和属性变量,然后使用BeanDefinitionLoader加载配置源,并注册到BeanDefinitionRegistry;


Spring Boot 对Spring BeanDefinitionReader进行了封装,o.s.boot. BeanDefinitionLoader, 它对Class、xml、Package、Groovry 的配置源,做了一个统一的适配。所以,可以在SpringApplication.run(Object[] configSource,String … args)方法中传入以上各种类型。


七、Spring配置是怎么加载


Spring对不同类型的配置源会使用不同类型的BeanDefinitionReader对其进行加载。




例如:xml 文件使用XmlBeanDefinitionReader,Groovy 使用GroovyBeanDefinitionReader;注解类使用AnnotatedBeanDefinitionReader,所不同的是AnnotatedBeanDefinitionReader并不是BeanDefinitionReader的实现类。


Spring 强大的注解扫描和注解解析能力:


Spring使用ClassPathBeanDefinitionScanner类,扫描classpath 中的注解类,在开始doScan之前,可以调用该类的addIncludeFilter和addExcludeFilter注册TypeFilter,来指定让该类扫描哪些类,和不扫描哪些类;


Spring 默认注册扫描@Component注解的所有类。


Spring 为什么没有把其他的注解类也注册到过滤器去呢?


Spring 的注解处理机制具有传递性,只要是被@Component注解的注解,都会进行扫描解析,例如我们常见的:@Service、@Controller、@Repository、@Configuration 等注解类,都是由@Component,因此,我们也可以使用这个机制进行自定义注解。


八、我们EOS8 用到了哪些

Spring/Spring Boot配置能力呢?


  • 在平台的功能模块加载中,我们使用spring.factories,用做模块自动配置。

  • 在微服务消费端加载微服务的代理时,使用到了自定义的Annotation。

  • 使用配置特定的参数,启动是 cloud 模式,还是开发模式。


九、总结


Spring Boot的自动配置很简单,主要总结为以下三步:

1. 在spring.factories的注册后,实现跨 jar 包自动加载

2. 基于 Condition 来实现条件配置

3. 自定义注解实现个性化扩展



关于作者虎振东,普元SOA&云计算部门资深软件工程师,8年软件开发设计经验,曾在歌华数媒架构设计开发多个广电和移动互联网融合项目,普元 EOS 8微服务平台核心开发工程师。




关于EAWorld微服务,DevOps,数据治理,移动架构原创技术分享,长按二维码关注


阅读原文:http://mp.weixin.qq.com/s?timestamp=1513587874&src=3&ver=1&signature=ijcZhJm3iY8ivJHvjNFvovzt1gWx3xCaAiGf30AkQFvDjx241wyqalLIQW9sCvX8020LVc9fAovkavzT6pWtCtSpWQVwADjOtiOwT94WoYIhjGMtfYWd4mzPudrE0X9ttUlyfdbSV2iu9-ogZfnR6p2WBoNoqTSlPweIcE*r89A=&devicetype=Windows-QQBrowser&version=61030004&pass_ticket=qMx7ntinAtmqhVn+C23mCuwc9ZRyUp20kIusGgbFLi0=&uin=MTc1MDA1NjU1&ascene=1
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容