SpringBoot学习(五)

87 阅读3分钟

这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战

通过之前的学习,了解了SpringBoot项目配置体系,这次就来学习一下SpringBoot是如何实现自动配置的。

SpringBoot自动配置原理

@SpringBootApplication注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {
    @Filter(type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class}), 
    @Filter(type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class})
    })
public @interface SpringBootApplication {
    ...
}
  • @SpringBootApplication注解作为一个组合注解,本身由@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan三个注解组合而成。
  • 在启动类中使用该三个注解代替@SpringBootApplication注解同样可以启动服务。

@ComponentScan注解

  • @ComponentScan是Spring中的注解,用来扫描基于指定包路径下的所有需要注入的类(@Component、@Repository等注解所标注的类),并把相关的Bean定义批量加载到Ioc容器中。
  • 可以通过basePackages属性来指定@ComponentScan扫描的范围,不指定时默认为@ComponentScan注解类所在包范围(即SpringBoot启动类包路径)。

@SpringBootConfiguration注解

  • @SpringBootConfiguration注解没有新增内容,只是使用了Spring中的@Configuration注解,而@Configuration注解中提供了JavaConfig配置类实现。
  • 使用@Configuration注解的类表示本身作为一个Ioc容器的配置类,Spring中有XML和JavaConfig两种配置方式,SpringBoot社区推荐使用JavaConfig的配置方式。
    • XML配置方式需要在xml文件中使用标签注册和使用bean对象的关系。
    • JavaConfig配置方式中使用@Configuration和@Bean注解来实现Spring配置类。其中@Configuration注解标识当前类作为Spring Ioc容器中bean的来源;@Bean注解方法则返回一个对象,并将该对象注册为Spring上下文中的bean。

@EnableAutoConfiguratuon注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    ...
}
  • @EnableAutoConfiguration注解与自动配置相关,借助@Import的帮助,将所有符合自动配置条件的bean定义加载到Ioc容器中。并根据类路径中的jar依赖为项目进行自动配置,如添加spring-boot-starter-web依赖,则SpringBoot会对Tomcat和Spring MVC进行自动配置。
  • @EnableAutoConfiguration注解同样是一个复合注解,包含@AutoConfigurationPackage@Import(AutoConfigurationImportSelector.class)两个注解。

@Import(AutoConfigurationImportSelector.class)

  • @Import(AutoConfigurationImportSelector.class)注解,借助EnableAutoConfigurationImportSelector将所有符合条件的@Configuration配置都加载到当前SpringBoot应用的Ioc容器中。
  • 借助于Spring框架中的SpringFactoriesLoader工具类,@EnableAutoConfiguration注解可以从指定的配置文件META-INF/spring.factories中加载配置。SpringFactoriesLoader会将@EnableAutoConfiguration的完整类名org.springframework.boot.autoconfigure.EnableAutoConfiguration作为Key,获取对应@Configuration类。

SpringBoot自动配置流程

  1. @EnableAutoConfiguration即开启自动配置注解,其通过SpringBootApplication注解标注到SpringBoot的启动类中,当启动类SpringBootApplication.run()执行时,@EnableAutoConfiguration注解便会生效。
  2. @EnableAutoConfiguration作为复合注解,其中包含了@Import(AutoConfigurationImportSelector.class)注解,引入了AutoConfigurationImportSelector类并执行其selectImports()方法。
  3. selectImports()方法内部使用了SpringFactoriesLoader.loadFactoryNames()方法来从classpath中扫描所有具有META-INF/spring.factories配置的Jar包。
  4. Jar包中的META-INF/spring.factories文件的内容以Key-Value形式存放,SpringFactoriesLoader类会以EnableAutoConfiguration的完整类名org.springframework.boot.autoconfigure.EnableAutoConfiguration作为Key,获取对应Value即一组以逗号分隔的XxxxAutoConfiguration类的全限定名。
  5. 针对获取到的所有XxxxAutoConfiguration类,其上标注有注解@EnableConfigurationProperties,并指定对应的XxxxProperties配置实体类,配置实体类上则使用@ConfigurationProperties注解来指向全局配置的属性值。
  6. 最终通过反射的方式实例化为对应的标注@Configuration的JavaConfig形式的Ioc容器配置类,最后汇总在一起加载到Ioc容器中。
  7. 至此,所有的全局配置属性对应的JavaConfig配置类会被自动封装成为bean并注入到Spring的Ioc容器中。