您的位置:首页 > 编程语言 > Java开发

Spring Boot自动配置原理

2020-02-29 18:59 656 查看

一、SpringBoot的自动配置原理

不知道大家第一次搭SpringBoot环境的时候,有没有觉得非常简单。无须各种的配置文件,无须各种繁杂的pom坐标,一个main方法,就能run起来了。与其他框架整合也贼方便,使用EnableXXXXX注解就可以搞起来了!

所以今天来讲讲SpringBoot是如何实现自动配置的~

1.1三个重要的注解

我们可以发现,在使用

main()
启动SpringBoot的时候,只有一个注解
@SpringBootApplication


我们可以点击进去@SpringBootApplication注解中看看,可以发现有三个注解是比较重要的:

  • @SpringBootConfiguration
    :我们点进去以后可以发现底层是Configuration注解,说白了就是支持JavaConfig的方式来进行配置(使用Configuration配置类等同于XML文件)。

  • @EnableAutoConfiguration
    :开启自动配置功能(后文详解)

  • @ComponentScan
    :这个注解,学过Spring的同学应该对它不会陌生,就是扫描注解,默认是扫描当前类下的package。将@Controller/@Service/@Component/@Repository等注解加载到IOC容器中。

所以,Application类可以被我们当做是这样的:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public class Java3yApplication {

public static void main(String[] args) {
SpringApplication.run(Java3yApplication.class, args);
}
}
1.2重点EnableAutoConfiguration

我们知道SpringBoot可以帮我们减少很多的配置,也肯定听过“约定大于配置”这么一句话,那SpringBoot是怎么做的呢?其实靠的就是

@EnableAutoConfiguration
注解。

简单来说,这个注解可以帮助我们自动载入应用程序所需要的所有默认配置。

如果你的类路径下有

tomcat-embedded.jar
包,那么你很可能就需要TomcatServletWebServerFactory

我们点进去看一下,发现有两个比较重要的注解:

  • @AutoConfigurationPackage
    :自动配置包

  • @Import
    :给IOC容器导入组件

1.2.1AutoConfigurationPackage

网上将这个

@AutoConfigurationPackage
注解解释成自动配置包,我们也看看
@AutoConfigurationPackage
里边有什么:

我们可以发现,依靠的还是@Import注解,再点进去查看,我们发现重要的就是以下的代码:

@Override
public void registerBeanDefinitions(AnnotationMetadata metadata,
BeanDefinitionRegistry registry) {
register(registry, new PackageImport(metadata).getPackageName());
}

在默认的情况下就是将:主配置类(@SpringBootApplication)的所在包及其子包里边的组件扫描到Spring容器中。

看完这句话,会不会觉得,这不就是ComponentScan的功能吗?这俩不就重复了吗?

我开始也有这个疑问,直到我看到文档的这句话:

it will be used when scanning for code @Entity classes.
It is generally recommended that you place EnableAutoConfiguration (if you're
not using  @SpringBootApplication) in a root package so that all sub-packages
and classes can be searched.

比如说,你用了Spring Data JPA,可能会在实体类上写

@Entity
注解。这个
@Entity
注解由
@AutoConfigurationPackage
扫描并加载,而我们平时开发用的
@Controller/@Service/@Component/@Repository
这些注解是由
ComponentScan
来扫描并加载的。
简单理解:这二者扫描的对象是不一样的。
1.2.2回到Import
我们回到
@Import(AutoConfigurationImportSelector.class)
这句代码上,再点进去
AutoConfigurationImportSelector.class
看看具体的实现是什么:

我们再进去看一下这些配置信息是从哪里来的(进去getCandidateConfigurations方法):

这里包装了一层,我们看到的只是通过SpringFactoriesLoader来加载,还没看到关键信息,继续进去:

简单梳理:

  • FACTORIES_RESOURCE_LOCATION
    的值是
    META-INF/spring.factories

  • Spring启动的时候会扫描所有jar路径下的

    META-INF/spring.factories
    ,将其文件包装成Properties对象

  • 从Properties对象获取到key值为

    EnableAutoConfiguration
    的数据,然后添加到容器里边。

    最后我们会默认加载113个默认的配置类:

    有兴趣的同学可以去翻一下这些文件以及配置类哦:

    官网文档参考:

https://docs.spring.io/spring-boot/docs/2.2.0.BUILD-SNAPSHOT/reference/html/using-spring-boot.html#using-boot-structuring-your-code
1.3总结

@SpringBootApplication
等同于下面三个注解:

  • @SpringBootConfiguration

  • @EnableAutoConfiguration

  • @ComponentScan

其中

@EnableAutoConfiguration
是关键(启用自动配置),内部实际上就去加载
META-INF/spring.factories
文件的信息,然后筛选出以
EnableAutoConfiguration
为key的数据,加载到IOC容器中,实现自动配置功能!

  • 点赞
  • 收藏
  • 分享
  • 文章举报
mojiezhao 发布了52 篇原创文章 · 获赞 2 · 访问量 2619 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: