网站建设 常用字体/爱站权重查询
034:SpringBoot配置解析源码分析
- 1 SpringBoot启动流程总结01
- 2 SpringBoot自定义外部扩展文件01
- 3 SpringBoot自定义外部扩展文件02
- 4 SpringBoot启动流程总结02
- 3 SpringBoot启动流程总结03
- 6 SpringBoot源码分析课程总结
1 SpringBoot启动流程总结01
课题内容:
- SpringBoot源码分析之配置文件解析原理
- SpringBoot启动流程整体源码总结
- Spring源码总结之Spring体系面试题复习
总结SpringBoot启动流程
核心分为两个步骤;
- 创建 SpringApplication对象
- 调用SpringApplication run 实现启动,同时返回当前的容器上下文
分析流程:
- 创建SpringApplication对象 SpringBoot容器初始化操作;
- 获取当前应用启动类型 原理:判断当前classpath是否有加载servlet类,如果有,返回Servlet web启动方式;
webApplicationType 分为三种类型:
1.响应式启动 (Spring5新特性)
2.None 不会嵌入web容器启动 (将SpringBoot项目放入外部服务器运行)
3.SERVLET 基于Web容器启动 - setInitializers 读取SpringBoot包下面的META-INF/spring.factories获取到对应ApplicationContextInitializer 装配到集合中;
- setListeners读取SpringBoot包下面的META-INF/spring.factories获取到对应ApplicationListener装配到集合中;
- mainApplicationClass 获取当前运行的主函数;
- 调用SpringApplication run方法实现启动;
- StopWatch stopWatch = new StopWatch(); 记录SpringBoot项目启动时间
2 SpringBoot自定义外部扩展文件01
自定义加载配置文件
引入依赖
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version>
</parent>
<dependencies><!-- sprinboot web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>
相关代码
@RestController
@Configuration
public class IndexController {@Value("${mayikt.name}")private String name;@RequestMapping("/")public String index(){return "SpringBoot源码分析" + name;}
}
public class MySpringApplicationRunListener implements SpringApplicationRunListener {@Overridepublic void starting() {System.out.println(">>>starting");}@Overridepublic void environmentPrepared(ConfigurableEnvironment environment) {// 配置文件读取到程序中 思路需要自己将本地文件读取到容器中,再放入到springboot容器Properties properties = new Properties();try {// 1. 读取我们的my.properties文件properties.load(this.getClass().getClassLoader().getResourceAsStream("my.properties"));// 2. 读取名称名称为myPropertySource propertySource = newPropertiesPropertySource("my", properties);//3. 将资源添加到springboot项目中MutablePropertySources propertySources = environment.getPropertySources();//4.通过该api接口可以将配置文件读取到springboot项目中propertySources.addLast(propertySource);} catch (IOException e) {e.printStackTrace();}}@Overridepublic void contextPrepared(ConfigurableApplicationContext context) {}@Overridepublic void contextLoaded(ConfigurableApplicationContext context) {}@Overridepublic void started(ConfigurableApplicationContext context) {}@Overridepublic void running(ConfigurableApplicationContext context) {}@Overridepublic void failed(ConfigurableApplicationContext context, Throwable exception) {}
}
@SpringBootApplication
public class AppMayikt {public static void main(String[] args) {SpringApplication springApplication = new SpringApplication(AppMayikt.class);springApplication.run(args);}
}
resources目录下文件
META-INF/spring.factories
org.springframework.boot.SpringApplicationRunListener=\
com.mayikt.MySpringApplicationRunListener
my.properties
mayikt.name= mayikt.com
运行结果:
3 SpringBoot自定义外部扩展文件02
报错原因,反射时没有构造函数,参考原代码增加构造函数。
public class MySpringApplicationRunListener implements SpringApplicationRunListener {private SpringApplication application;private String[] args;public MySpringApplicationRunListener(SpringApplication application, String[] args) {this.application = application;this.args = args;}……
}
测试结果:
4 SpringBoot启动流程总结02
- getRunListeners(args); 读取META-INF/spring.factories 文件中SpringApplicationRunListeners 类型存入到集合中;
- listeners.starting(); 循环调用监听器starting方法;
- ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
listeners.environmentPrepared(environment);
读取配置文件到SpringBoot容器中;
读取配置有多种来源:classpath:/,classpath:/config/,file:./,file:./config/
classpath 与file读取有哪些区别?
Classpath 读取编译后的配置文件内容;File读取编译前的配置文件。
默认读取配置文件名称为:application
SpringBoot支持 yml、yaml、xml、properties类型配置文件读取。
3 SpringBoot启动流程总结03
- Banner printedBanner = printBanner(environment); 打印SpringBoot Banner;
- 创建SpringBoot上下文AnnotationConfigServletWebServerApplicationContext对象(java反射机制初始化);
- refreshContext(context); 刷新上下文,会走到spring里面refresh方法;
- 开始创建tomcat容器;
- 开始加载SpringMVC;
- afterRefresh 定义一个空的模版给其他子类实现重写;
- listeners.started(context); 使用广播和回调机制通知监听器SpringBoot容器已经启动成功;
- listeners.running(context); 使用广播和回调机制通知监听器可以正常运行SpringBoot项目;
- 最后返回当前上下文context。
(原内容由每特教育&蚂蚁课堂余老师编写,稍作修改)
SpringApplication类run方法源码:
public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();configureHeadlessProperty();SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting();try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);configureIgnoreBeanInfo(environment);Banner printedBanner = printBanner(environment);context = createApplicationContext();exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,new Class[] { ConfigurableApplicationContext.class }, context);prepareContext(context, environment, listeners, applicationArguments,printedBanner);refreshContext(context);afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}listeners.started(context);callRunners(context, applicationArguments);}catch (Throwable ex) {handleRunFailure(context, listeners, exceptionReporters, ex);throw new IllegalStateException(ex);}listeners.running(context);return context;
}
6 SpringBoot源码分析课程总结
Spring体系核心设计模式分析:
Spring中有那些启动方式? 注解和xml
Spring中常用注解有那些:@ComponentScan、@Component、@Configuration、@Baan、@import
SpringBean的生命周期最核心组件:后置处理器
Spring事务底层原理,为什么会失效的呢?Aop技术,不能try
SpringAop中五个通知如何形成调用关联:=责任链模式和递归方法
Spring循环依赖是如何解决的呢?解决循环依赖底层原理什么?三级缓存
SpringMVC 如何去除web.xml运行的? 实现ServletContainerInitializer接口
SpringMVC适配器模式用于在什么地方?Handler多种类型处理
SpringBoot原理是什么?快速整合第三方框架、注解、内嵌tomcat
Springboot启动流程? 创建 SpringApplication对象,run启动
如何手写SpringBoot?三大核心理念+自定义starter+内嵌tomcat+使用Spring注解包装一遍