详解Spring Boot 自动配置机制

一、简介

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. 自定义注解实现个性化扩展

原文发布于微信公众号 - EAWorld(eaworld)

原文发表时间:2017-12-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java后端技术

context:component-scan标签的use-default-filters属性的作用以及原理分析

  我们在Spring+SpringMVC+Mybatis的集成开发中,经常会遇到事务配置不起作用等问题,那么本文就来分析下出现这种问题可能的原因以及解决方式。

9740
来自专栏Linyb极客之路

Spring Boot 2.0迁移指南主要注意点

Spring官方的Spring Boot 2变动指南,主要是帮助您将应用程序迁移到Spring Boot 2.0,变化部分还是很多很细节的,摘录主要点如下: S...

10640
来自专栏Java学习网

Spring 3.0支持基于rest的Web服务学习总结

尽管RESTful功能被添加到Spring MVC框架非常早期通过注释和其他API功能,支持基于rest的Web服务是Spring MVC有点晚。几个jax -...

239100
来自专栏开发与安全

linux网络编程之进程间通信基础(一):进程间通信概述

一、顺序程序与并发程序特征 顺序程序特征 顺序性 封闭性:(运行环境的封闭性) 确定性 可再现性 并发程序特征 共享性 并发性 随机性 二、进程互斥 ...

18200
来自专栏Danny的专栏

【EJB学习笔记】——EJB开发环境搭建(Eclipse集成JBoss)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

16930
来自专栏ImportSource

Spring Boot 2.0 新特性和发展方向

以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Java 6 和 7 不再支持。 内嵌容器包结构调整 为了支持react...

45590
来自专栏芋道源码1024

注册中心 Eureka 源码解析 —— 项目结构简介

本文主要基于 Eureka 1.8.X 版本 1. 概述 1.1 简介 1.2 项目结构 2. eureka-client 2.1 eureka-client-...

47680
来自专栏Gaussic

基于Spring Boot 的Blog开发 原

之前写过几篇关于利用Spring MVC来开发的博客,从博客下面的评论以及GitHub上的Issues看还是会出现许多的问题,且大部分的问题都出在配置上。虽然说...

10210
来自专栏Jaycekon

Spring-Boot:6分钟掌握SpringBoot开发

 构建项目 从技术角度来看,我们要用Spring MVC来处理Web请求,用Thymeleaf来定义Web视图,用Spring Data JPA来把阅读列表持久...

47160
来自专栏cloudskyme

虚拟化平台cloudstack(7)——新版本的调试

调试环境 ubuntu 12.04 JDK1.7 apache-maven-3.10 eclipse 4.2 Juno mysql 5 源码下载及调试 上面的几...

35950

扫码关注云+社区

领取腾讯云代金券