Spring Boot中的initializers的作用分析
在SpringApplication的实例属性中有一个初始器的属性:List<ApplicationContextInitializer<?>> initializers ,这些初始化器(initializers)是Spring Boot通过读取每个jar包下的/META-INF/spring.factories文件中的配置获取的。每一个initailizer都是一个实现了ApplicationContextInitializer接口的实例。ApplicationContextInitializer是Spring IOC容器中提供的一个接口:
package org.springframework.context;
public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {
/**
* Initialize the given application context.
* @param applicationContext the application to configure
*/
void initialize(C applicationContext);
}
ApplicationContextInitializer是一个回调接口,它会在ConfigurableApplicationContext的refresh()方法调用之前被调用,做一些容器的初始化工作。这一点我们也可以通过SpringApplication的实例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); // prepareContext方法中将会执行每个initializers的逻辑
refreshContext(context); // 执行bean的创建和实例化
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);
}
}
SpringBoot默认情况下提供了6个initializer,分别由2个jar提供:
spring-boot-1.5.2.RELEASE.jar
- org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,
- org.springframework.boot.context.ContextIdApplicationContextInitializer,
- org.springframework.boot.context.config.DelegatingApplicationContextInitializer,
- org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer
spring-boot-autoconfigure-1.5.2.RELEASE.jar
- org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,
- org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
Spring Boot对initializer的获取过程如下:
initialize(Object[] sources)
-->(Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class )) //获取initializer实例
-->SpringFactoriesLoader.loadFactoryNames(type, classLoader))
-->createSpringFactoriesInstances(type, parameterTypes,classLoader, args, names)
-->Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes)
-->T instance = (T) BeanUtils.instantiateClass(constructor, args)
-->AnnotationAwareOrderComparator.sort(instances)
--> setInitializers(Collection<? extends ApplicationContextInitializer<?>> initializers)
-->this.initializers = new ArrayList<ApplicationContextInitializer<?>>();
-->this.initializers.addAll(initializers); //存入List<ApplicationContextInitializer<?>> initializers
Spring Boot中的initializers的作用分析的更多相关文章
- 【spring boot】spring boot中使用@RestController不起作用,不返回json,依旧去找访问接口的请求地址对应的页面
问题描述: spring boot中使用@RestController不起作用,不返回json,依旧去找访问接口的请求地址对应的页面 表现结果: 1>使用postman测试接口,表现为返回是40 ...
- 关于Spring Boot中的业务层(Service)是否要创建接口的分析
在借助Spring Boot框架开发web项目时,在业务层(Service)这一部分,标准做法是:定义一个接口,然后再一个或多个类去实现.那么疑问来了: 为什么我们要维护两份同构代码,而不直接使用一个 ...
- Spring Boot 启动(一) SpringApplication 分析
Spring Boot 启动(一) SpringApplication 分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html ...
- Spring Boot 揭秘与实战 源码分析 - 开箱即用,内藏玄机
文章目录 1. 开箱即用,内藏玄机 2. 总结 3. 源代码 Spring Boot提供了很多”开箱即用“的依赖模块,那么,Spring Boot 如何巧妙的做到开箱即用,自动配置的呢? 开箱即用,内 ...
- Spring Boot自动装配原理源码分析
1.环境准备 使用IDEA Spring Initializr快速创建一个Spring Boot项目 添加一个Controller类 @RestController public class Hell ...
- Spring Boot中使用时序数据库InfluxDB
除了最常用的关系数据库和缓存之外,之前我们已经介绍了在Spring Boot中如何配置和使用MongoDB.LDAP这些存储的案例.接下来,我们继续介绍另一种特殊的数据库:时序数据库InfluxDB在 ...
- Spring Boot中的事务管理
原文 http://blog.didispace.com/springboottransactional/ 什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合 ...
- Spring Boot中的注解
文章来源:http://www.tuicool.com/articles/bQnMra 在Spring Boot中几乎可以完全弃用xml配置文件,本文的主题是分析常用的注解. Spring最开始是为了 ...
- Spring Boot中使用Swagger2构建API文档
程序员都很希望别人能写技术文档,自己却很不愿意写文档.因为接口数量繁多,并且充满业务细节,写文档需要花大量的时间去处理格式排版,代码修改后还需要同步修改文档,经常因为项目时间紧等原因导致文档滞后于代码 ...
随机推荐
- jenkins配置小结
启动jenkins:javaw -jar -Dhudson.model.DirectoryBrowserSupport.CSP= jenkins.war --httpPort=8001 wget h ...
- 降维方法PCA与SVD的联系与区别
在遇到维度灾难的时候,作为数据处理者们最先想到的降维方法一定是SVD(奇异值分解)和PCA(主成分分析). 两者的原理在各种算法和机器学习的书籍中都有介绍,两者之间也有着某种千丝万缕的联系.本文在简单 ...
- 决策树decision tree原理介绍_python sklearn建模_乳腺癌细胞分类器(推荐AAA)
sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003& ...
- python如何直接控制鼠标键盘
一.简介 我们知道在windows下输入:win + r,会弹出下面的窗口,而在下面的窗口出现后我们接着按下esc键,下面的窗口会消失 现在设想我们想在python代码里控制键盘,想通过运行代码-&g ...
- 剑指offer面试题4: 二维数组中的查找
题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...
- cxf与spring的整合
cxf与spring的整合: 一:服务端相关配置(配置好后启动tomocat就自动发布了接口,浏览器打开验证下) 1:导入cxf以及spring的相关jar包; 2:在web.xml中增加配置: 代码 ...
- dependencies和devDependencies两者区别
在npm生成的package.json文件中,有devDependencies和dependencies两个环境 devDependencies 用于开发环境(本地) dependencies 用于生 ...
- error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools
解决方案 1. http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted 下载twisted对应版本的whl文件(我的Twisted‑17.5.0‑cp36 ...
- [笔记]New in Chrome 66
原文 CSS Typed Object Model 使用CSS object model,返回的一切都是字符串 el.style.opacity = 0.3; console.log(typeof e ...
- TS-Node 体验
[给链接不赘述][提醒坑][想更简单学计算机必须会看懂英语][win让你专注代码未来深入linux][尽管文件恨多,但是我们不去dissect 是永远不会的] https://www.tslang.c ...