Spring Boot源码分析——自动配置

SpringBoot yan loading.. 0评论

Spring Boot以spring-boot-starter-xx命名的模块都是“开箱即用”模块,意思是说,当开发者完成依赖添加后(即pom文件的依赖添加),这个功能就会自动创建和注入到上下文中,不需要再编写麻烦的配置,只需要提供参数属性即可。十分的方便,那么如此巧妙的开箱即用是怎么实现的呢?

本文将探索其中的奥秘,笔者模拟编写自动装载JDBC的过程:

为了方便学习,将自动配置分为三部分进行理解:

  1. 业务类(待检测类)DemoJDBCService:通常使用Maven引入依赖,或Jar包等方式引入类。
  2. 自动配置类JDBCAutoConfiguration:判断业务类是否存在,若存在对业务类进行初始化、装载,比如完成读取参数、初始化等操作。
  3. 扫描加载自动配置类AutoConfigurationImportSelector:调用自动配置类。

业务类

自动配置的触发点,被检测的核心业务类,若该类存在才会进行自动配置,实现“开箱即用”的功能,否则不执行配置。

例子中,采用最简单的业务,代码如下:

注意:这个类不能被component-scan扫描到。该bean应该由自动配置进行装载,如果被扫描到顺序不同,不符合逻辑会产生错误。(这其实是不可避免的“缺陷”,读者可以尝试在自己的项目中扫描 org.spring 会发现项目无法启动)

通俗点理解,假设本类中还依赖JDBC的相关库,如果没有加载相关库,被component-scan扫描到必然会报错NoClassDefFoundError。如果是自动装载类加载,装载类会先判断是否存在相关库,存在再加载 这时就不会报错。

自动配置类

自动配置分为三步:

(1)从application.properties中读取参数;

(2)完成对业务类Bean的初始化、装载;

(3)配置spring.factories

读取参数

方法一:

Spring 提供了一个注解用于导入配置文件中的数据 — @Value 。

参数的key代表properties中的key,value是默认值,即若不存在该key时的取值。

注意:直接填写会当做字符串处理,如果想设null应填写#{null}

方法二:(本例采用该方法)

创建属性参数类JDBCProperties,用来读取并管理参数

在属性参数文件application.properties 中,读取前缀为custom的属性。如针对上述代码,配置中应写:

初始化装载

这是最核心的地方

  1. 首先利用@Conditional等注解判断业务类是否存在。若存在则继续。
  2. @EnableConfigurationProperties注解来加载配置参数对象
  3. 编写Resolver方法,利用参数初始化装载业务Bean

spring.factories

配置spring.factories,添加上刚刚定义的自动配置类。用于运行时扫描自动加载类时使用,否则将无法加载该配置

这里是采用系统的自动装载扫描类EnableAutoConfiguration,也可以用户自行编写。(具体后面会详细介绍)

扫描加载配置

自动扫描的过程可以自行编写,本例中采用spring中自带的流程进行源码讲解。

  1. 主函数通过@EnableAutoConfiguration注解,利用其内@Import方法导入利用AutoConfigurationImportSelector类
  2. 利用AutoConfigurationImportSelector类完成spring.factories文件的扫描,从而加载配置。

@EnableAutoConfiguration

@Import , 这个注解可以导入一个配置类到另一个配置类中。在 Spring4.2 中对这个注解进行了加强,可以直接将一个类加入Spring容器。那么只要写上 @Import(AutoConfigurationImportSelector.class) 即可。

AutoConfigurationImportSelector类

该类是实现与ImportSelector接口,该接口作用与注解 @Import类似。

其中核心方法selectImports,根据 importingClassMetadata 的值,从带有注解 @Configuration 的类中选择并返回合适的类名数组,将其导入 Spring 容器。因此,查看AutoConfigurationImportSelector类中的ImportSelector方法,就是导入自动配置的地方

可见本方法中,主要是getCandidateConfigurations 方法获取类名,之后经过一些处理,把名返回完成spring的导入。

getCandidateConfigurations方法中通过 SpringFactoriesLoader.loadFactoryNames 扫描 spring.factories 文件获得类名。这里就不再深入看了。

Main函数测试

关注<爱上极客>公众号,定期推送精彩内容!

喜欢 (0)

如未说明则本站原创,转载请注明出处:爱上极客 » Spring Boot源码分析——自动配置


0
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址