Spring Boot 2自动配置原理

目录

1.@AutoConfigurationPackage注解的作用是什么?

2.@Import(AutoConfigurationImportSelector.class)又是在做什么?

3.Spring Boot中 Spring MVC是如何实现自动配置的?


用过Spring Boot并且长得帅的人都知道,应用的启动类上,只要有@SpringBootApplication注解,就是一个Spring Boot的应用,就会按自动配置所需的Bean。怎么做到的呢?

唯一的线索就是@SpringBootApplication注解本身了。Ctrl + 单击点开这个注解,会看到它身上附带了3个其它注解(@Target等元注解除外),其中一个@EnableAutoConfiguration和我们要研究的自动配置有关,它打开了整个项目自动配置的开关。

这个注解怎么做到的开启自动配置呢?继续Ctrl + 单击点开@EnableAutoConfiguration注解,会看到它身上附带了两个注解。

看来秘密都在这里面,我们需要好好研究一下这两个注解。先看看第一个吧!

1.@AutoConfigurationPackage注解的作用是什么?

点开这个注解,会看到它身上别的什么都没有,只是导入了一个名叫 AutoConfigurationPackages.Registrar 的内部类。

点开 Registrar 这个类,发现它实现了Spring框架的 ImportBeanDefinitionRegistrar 接口,那么它实现的 registerBeanDefinitions() 在启动时会被 Spring 调用。registerBeanDefinitions() 里面调用了register() 方法,看方法名是在注册什么东西,我猜的。>_>

看看 register() 这个方法里面有什么骚操作。是不是看不懂这个代码?必须在这里打个断点调试一下了。

看看这段代码,通过代码的方式创建了一个Bean,类型是 BasePackage(基础包),把本项目的基础包名 cn.itrip 设置进去了,最后把Bean注册到了Spring 的 IoC 容器中,Bean的 name 是 org.springframework.boot.autoconfigure.AutoConfigurationPackages 。其实这是 Spring 中另一种把Bean 注册到 IoC 容器的方式,和类上加@Service、@Component注解效果一样。

总结一下,@AutoConfigurationPackage注解 的主要目的,就是把 cn.itrip 包加入到了需要自动配置的包的集合中。难怪Spring Boot项目的启动类所在的同级包会自动配置Bean,原来是这里添加的入口。

2.@Import(AutoConfigurationImportSelector.class)又是在做什么?

首先需要了解,Spring框架提供的 ImportSelector 接口用来选择性地导入有 @Configuration 注解的类。此处导入的 AutoConfigurationImportSelector 类实现了 ImportSelector 接口,因此它的 process() 在启动时会被 Spring 框架调用。

看上面调试的截图,左下角是线程栈的调用路径,调用的顺序是 process() -> getAutoConfigurationEntry() -> getCandidateConfigurations() 。中间发生什么我们先不管,但是到了 getCandidateConfigurations() 方法,我们可以看到此处有Assert 断言,以及错误提示讲到在 META-INF/spring.factories 文件找不到自动配置类。

进一步追踪这个方法,它又调用了SpringFactoriesLoader.loadFactoryNames() -> loadSpringFactories () ,确实去 META-INF/spring.factories 加载了。那么这个文件里面有什么宝贝东西呢?打开这个文件看一下,它就在Spring Boot的自动配置jar包中。

可以看到这个 spring.factories 文件里面都是列举了Spring 可以集成的各种模块、第三方框架或中间件的自动配置类,类名都是 XxxAutoConfiguration 的形式。这各个 XxxAutoConfiguration 其实也在同一个jar包中,分别负责对导入了依赖的各模块、第三方框架进行Bean的自动配置。

具体如何做到的,以我们Web项目常用的 SpringMVC 框架来说吧。

3.Spring Boot中 Spring MVC是如何实现自动配置的?

我们知道,在Spring Boot中要使用Spring MVC框架,只需导入一个 spring-boot-starter-web 启动器即可。传统Spring XML需要配置那么多Bean,也不需要我们配置了,那么是不是自动配置的原因呢?根据上一节说的,先看看spring.factories文件中关于web的自动配置,列举了哪些自动配置类。

根据经验,看名称先猜一下,Spring MVC的前端控制器 DispatcherServlet 应该是由上图红框中第一条的 DispatcherServletAutoConfiguration 类负责创建的。为了证实一下,打开 DispatcherServletAutoConfiguration 类看看。

首先看到的是类上几个注解。

  • @AutoConfigurationOrder 注解指定了执行顺序,最先执行;
  • @Configuration 注解说明本类可以用作定义各种带@Bean的工厂方法;
  • @ConditionOnWebApplication注解说明只有在Web项目环境,才会配置本类的Bean;
  • @ConditionOnClass(DispatcherServlet.class)说明只有在你导入了Spring MVC包的依赖(classpath下能搜索到DispatcherServlet 类)的情况下,才会配置本类的Bean;
  • @AutoConfigureAfter 注解指定了,要想配置本类的Bean,必须先创建 ServletWebServerFactoryAutoConfiguration 类的Bean。

从上图代码中的常量可以看到,自动配置的前端控制器,在IoC容器中的Bean名称也叫做 dispatcherServlet 。

当然,关于Spring MVC的自动配置还有一个类不得不说,就是 WebMvcAutoConfiguration类。传统Spring MVC需要在xml中配置的视图解析器、消息转换器等 Bean,都在这个自动配置类中创建了Bean。

天天写代码多无聊,一起来玩微信视频号啊!

猜你喜欢

转载自blog.csdn.net/liudun_cool/article/details/108193207