3. SpringBoot ——自动配置原理浅析
SpringBoot的功能之所以强大,离不开它的自动配置这一大特色。但估计很多人只是知其然而不知其所以然。下面本人对自动配置原理做一个分析:
在使用SpringBoot时我们通过引入不同的Starter,就自动地应用其相应的自动配置。这是由于每个Starter都会引一个相应xxx--autoconfigure.jar,并且在这个jar的META-INF/spring.factories文件中有类似如下的配置:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
也就是通过org.springframework.boot.autoconfigure.EnableAutoConfiguration这个为 key引入自动配置类。这个自动类就会以代码的方式去完成以前Spring的xml配置文件做的事。
现在的关键问题就是,Spring的容器是如何知道这个自动配置类的存在的呢?带着这个问题,我们来跟踪SpringBoot启动类的实例run方法,先列出方法源码:
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
analyzers = new FailureAnalyzers(context);
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
listeners.finished(context, null);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
return context;
}
catch (Throwable ex) {
handleRunFailure(context, listeners, analyzers, ex);
throw new IllegalStateException(ex);
}
}
其实整个过程的秘密全在上面这段代码中体现出来了,只不过隐藏的比较深而已。上面这段有两个方法是和Spring容器发现这个自动配置类有关的
1. 在这个 prepareContext(context, environment, listeners, applicationArguments,printedBanner)
方法中完成了SpringBoot 的main方法中的启动类在Spring容器中的注册,并且是以源的方式进行注册。也就是相当于告诉spring容器,这个启动类就相当于是以前的xml文件了
2. refreshContext(context);
这个就是初始化 Spring容器,并实例化容器中注册的Bean,自然也就会对SpringBoot 的main方法中的启动类进行解析,这样一来,启动类上的 注解 @EnableAutoConfiguration就起作用了,但是要注意@EnableAutoConfiguration注解是springBoot提供的,springframeworke中的ApplicationContext是不会理会它的,而springboot接管后,相应的容器也是springBoot提供的,所以@EnableAutoConfiguration注解才会起作用,在createApplicationContext()中能看到springboot使用的容器类。
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET:
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE:
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default:
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Unable create a default ApplicationContext, "
+ "please specify an ApplicationContextClass",
ex);
}
}
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
下面看 @EnableAutoConfiguration的源码:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; /**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
Class<?>[] exclude() default {}; /**
* Exclude specific auto-configuration class names such that they will never be
* applied.
* @return the class names to exclude
* @since 1.3.0
*/
String[] excludeName() default {}; }
会发现这个 @EnableAutoConfiguration 注解里面 @Import(AutoConfigurationImportSelector.class)
AutoConfigurationImportSelector里面有几段代码说明其会从META-INF/spring.factories文件,并加载其中配置key为org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的类,我们称之为自动配置类,这样类上都会有@Configuration注解,所以就能被spring容器处理了。
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
Assert.notEmpty(configurations,
"No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
} /**
* Return the class used by {@link SpringFactoriesLoader} to load configuration
* candidates.
* @return the factory class
*/
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
总结:
@SpringBootApplication —— > @EnableAutoConfiguration ——> AutoConfigurationImportSelector——>META-INF/spring.factories
至此,一切真相大白。
3. SpringBoot ——自动配置原理浅析的更多相关文章
- 这样讲 SpringBoot 自动配置原理,你应该能明白了吧
https://juejin.im/post/5ce5effb6fb9a07f0b039a14 前言 小伙伴们是否想起曾经被 SSM 整合支配的恐惧?相信很多小伙伴都是有过这样的经历的,一大堆配置问题 ...
- springboot自动配置原理以及手动实现配置类
springboot自动配置原理以及手动实现配置类 1.原理 spring有一个思想是"约定大于配置". 配置类自动配置可以帮助开发人员更加专注于业务逻辑开发,springboot ...
- SpringBoot自动配置原理
前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 回顾前面Spring的文章(以学习的顺序排好): S ...
- SpringBoot实战之SpringBoot自动配置原理
SpringBoot 自动配置主要通过 @EnableAutoConfiguration, @Conditional, @EnableConfigurationProperties 或者 @Confi ...
- SpringBoot自动配置原理学习
介绍 构建Springboot项目时我们会创建一个启动类 @SpringBootApplication public class DemoApplication { public static voi ...
- 浅谈springboot自动配置原理
前言 springboot自动配置关键在于@SpringBootApplication注解,启动类之所以作为项目启动的入口,也是因为该注解,下面浅谈下这个注解的作用和实现原理 @SpringBootA ...
- SpringBoot系列二:SpringBoot自动配置原理
主程序类的注解 @SpringBootApplication 注解,它其实是个组合注解,源码如下: @Target({ElementType.TYPE}) @Retention(RetentionPo ...
- springBoot 自动配置原理--自己新建一个 starter
上篇我们说到 springboot 和 SSM 框架的区别,今天我们就看看 springboot 到底为我们做了哪些事情,让我们开发变得如此简单. springboot 中起着重要作用的是 start ...
- springBoot 自动配置原理
在之前文章中说过,springBoot会根据jar包去添加许多的自动配置,本文就来说说为什么会自动配置,自动配置的原理时什么? springBoot在运行SpringApplication对象实例化时 ...
随机推荐
- 【.NET】asp.net Redirect 图片路径
#需求: 前端通过<img>的src向服务端请求图片信息,如果不存在想要的图片,那么就返回一张默认路径下的图片: #实现: <img class="related_reso ...
- Netsarang
下载 https://www.netsarang.com/zh/all-downloads/ 建议直接下载 xmanager-power-suite,里面包含了 Xmanager.Xshell.Xft ...
- web.xml 文件头
Servlet 2.3 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN ...
- Windows Azure中国版试用
Winodws Azure刚出来那会都没怎么关注,就在一些网页新闻上见过一些报道,之前阿里云在博客里搞过推广,拿什么豆可以换,当时也就是看了一下没去用过. 有次在一群里别人说Windows Azure ...
- DosBox 的 DOSBOX.CONF 的详细配置说
1.首先下载 DOSbox 0.72 版. 2.下载完毕,开始安装.安装到任意目录均可.安装完毕会在开始菜单生成程序组,DOSBox.conf 文件是 DOSbox 的配置文件,保持默认配置就可 ...
- IIS 常见异常及解决办法
Ø 简介 IIS 是我们平常接触比较多的服务端软件,用于站点发布等,本文主要记录 IIS 常见的异常及解决办法.主要包括: 1. Visual Studio 启动 Web 项目提示"无 ...
- C# WinForm开发系列 - Crystal Report水晶报表
转自:ttp://www.cnblogs.com/peterzb/archive/2009/07/11/1521325.html 水晶报表(Crystal Report)是业内最专业.功能最强的报表系 ...
- 练习:javascript弹出框及地址选择功能,可拖拽
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 利用xpath爬取招聘网的招聘信息
爬取招聘网的招聘信息: import json import random import time import pymongo import re import pandas as pd impor ...
- LOJ #2183「SDOI2015」序列统计
有好多好玩的知识点 LOJ 题意:在集合中选$ n$个元素(可重复选)使得乘积模$ m$为$ x$,求方案数对$ 1004535809$取模 $ n<=10^9,m<=8000且是质数,集 ...