SpringBoot01-启动类启动做了那些事情
1.第一个步骤进入SpringApplication构造函数
- public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
- this.resourceLoader = resourceLoader;
- Assert.notNull(primarySources, "PrimarySources must not be null");
- this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
- this.webApplicationType = WebApplicationType.deduceFromClasspath();//这个type是SERVLET
- setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));//设置初始化
- setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));//设置监听器
- this.mainApplicationClass = deduceMainApplicationClass();
- }
1.1 看一下 setInitializers 方法做了些什么事情
- // type 是 ApplicationContextInitializer.class
- private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
- ClassLoader classLoader = getClassLoader();//
- // Use names and ensure unique to protect against duplicates
- Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));//返回ApplicationContextInitializer对应的类路径
- List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);//
- AnnotationAwareOrderComparator.sort(instances);
- return instances;
- }
返回ApplicationContextInitializer对应的类路径
- public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
- String factoryTypeName = factoryType.getName();//ApplicationContextInitializer
- //加载/META-INF/spring.factories下面的文件,并获取ApplicationContextInitializer为key对应的值
- return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
- }
根据类路径反射生成类的实例
- private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,
- ClassLoader classLoader, Object[] args, Set<String> names) {
- List<T> instances = new ArrayList<>(names.size());
- for (String name : names) {
- try {
- Class<?> instanceClass = ClassUtils.forName(name, classLoader);
- Assert.isAssignable(type, instanceClass);
- Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
- T instance = (T) BeanUtils.instantiateClass(constructor, args);
- instances.add(instance);
- }
- catch (Throwable ex) {
- throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
- }
- }
- return instances;
- }
1.2 setListeners做了什么
- //type = ApplicationListener.class 和上面一样获取ApplicationListener的类实例
- private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
- ClassLoader classLoader = getClassLoader();
- // Use names and ensure unique to protect against duplicates
- Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
- List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
- AnnotationAwareOrderComparator.sort(instances);
- return instances;
- }
1.3 获取主类
- private Class<?> deduceMainApplicationClass() {
- try {
- StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
- for (StackTraceElement stackTraceElement : stackTrace) {
- if ("main".equals(stackTraceElement.getMethodName())) {
- return Class.forName(stackTraceElement.getClassName());
- }
- }
- }
- catch (ClassNotFoundException ex) {
- // Swallow and continue
- }
- return null;
- }
2.第二个步骤调用run方法
- public ConfigurableApplicationContext run(String... args) {
- StopWatch stopWatch = new StopWatch();
- stopWatch.start();
- ConfigurableApplicationContext context = null;
- Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
- configureHeadlessProperty();//配置handless参数
- 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, ex, exceptionReporters, listeners);
- throw new IllegalStateException(ex);
- }
- try {
- listeners.running(context);
- }
- catch (Throwable ex) {
- handleRunFailure(context, ex, exceptionReporters, null);
- throw new IllegalStateException(ex);
- }
- return context;
- }
2.1 设置系统handless参数
- private static final String SYSTEM_PROPERTY_JAVA_AWT_HEADLESS = "java.awt.headless";
- private void configureHeadlessProperty() {
- System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS,
- System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless)));
- }
2.2 获取SpringApplicationRunListeners的实例
- private SpringApplicationRunListeners getRunListeners(String[] args) {
- Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
- return new SpringApplicationRunListeners(logger,
- getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
- }
2.3 准备环境
- private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
- ApplicationArguments applicationArguments) {
- // Create and configure the environment
- ConfigurableEnvironment environment = getOrCreateEnvironment();// new StandardServletEnvironment() 创建Servlet环境
- configureEnvironment(environment, applicationArguments.getSourceArgs());
- ConfigurationPropertySources.attach(environment);
- listeners.environmentPrepared(environment);
- bindToSpringApplication(environment);
- if (!this.isCustomEnvironment) {
- environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
- deduceEnvironmentClass());
- }
- ConfigurationPropertySources.attach(environment);
- return environment;
- }
2.4 console开启banner
- 图片配置路径:spring.banner.image.location
- 图片配置名称:banner.{ "gif", "jpg", "png" }
- 文本配置路径:spring.banner.location
- 默认数据resource下的:banner.txt
2.5 创建上下文类
- public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."
- + "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";
- protected ConfigurableApplicationContext createApplicationContext() {
- contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
- return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
- }
2.6 准备上下文
- private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
- SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
- context.setEnvironment(environment);
- postProcessApplicationContext(context);
- applyInitializers(context);
- listeners.contextPrepared(context);
- if (this.logStartupInfo) {
- logStartupInfo(context.getParent() == null);
- logStartupProfileInfo(context);
- }
- // Add boot specific singleton beans
- ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
- beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
- if (printedBanner != null) {
- beanFactory.registerSingleton("springBootBanner", printedBanner);
- }
- if (beanFactory instanceof DefaultListableBeanFactory) {
- ((DefaultListableBeanFactory) beanFactory)
- .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
- }
- if (this.lazyInitialization) {
- context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
- }
- // Load the sources
- Set<Object> sources = getAllSources();
- Assert.notEmpty(sources, "Sources must not be empty");
- load(context, sources.toArray(new Object[0]));
- listeners.contextLoaded(context);
- }
SpringBoot01-启动类启动做了那些事情的更多相关文章
- springBoot项目启动类启动无法访问
springBoot项目启动类启动无法访问. 网上也查了一些资料,我这里总结.下不来虚的,也不废话. 解决办法: 1.若是maven项目,则找到右边Maven Projects --->Plug ...
- springboot 启动类启动跳转到前端网页404问题的两个解决方案
前段时间研究springboot 发现使用Application类启动的话, 可以进入Controller方法并且返回数据,但是不能跳转到WEB-INF目录下网页, 前置配置 server: port ...
- 【spring boot】启动类启动 错误: 找不到或无法加载主类 com.codingapi.tm.TxManagerApplication 的解决方案
导入的一个外部的spring boot项目,运行启动类,出现错误:找不到或无法加载主类 com.codingapi.tm.TxManagerApplication 解决方案: 将所有错误处理完成后,再 ...
- 【spring cloud】子模块module -->导入一个新的spring boot项目作为spring cloud的一个子模块微服务,怎么做/或者 每次导入一个新的spring boot项目,IDEA不识别子module,启动类无法启动/右下角没有蓝色图标
如题:导入一个新的spring boot项目作为spring cloud的一个子模块微服务,怎么做 或者说每次导入一个新的spring boot项目,IDEA不识别,启动类无法启动,怎么解决 下面分别 ...
- asp.net core 系列 2 启动类 Startup.CS
学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 在探讨Startup启动类之前,我们先来了解下Asp.NET CORE 配置应用程序的执行顺序 ...
- 避免在ASP.NET Core 3.0中为启动类注入服务
本篇是如何升级到ASP.NET Core 3.0系列文章的第二篇. Part 1 - 将.NET Standard 2.0类库转换为.NET Core 3.0类库 Part 2 - IHostingE ...
- 精尽Spring Boot源码分析 - SpringApplication 启动类的启动过程
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
- 4.3、Libgdx启动类和配置
(原文:http://www.libgdx.cn/topic/45/4-3-libgdx%E5%90%AF%E5%8A%A8%E7%B1%BB%E4%B8%8E%E9%85%8D%E7%BD%AE) ...
- Spring Boot SpringApplication启动类(二)
目录 前言 1.起源 2.SpringApplication 运行阶段 2.1 SpringApplicationRunListeners 结构 2.1.1 SpringApplicationRunL ...
- Spring Boot SpringApplication启动类(一)
目录 目录 前言 1.起源 2.SpringApplication 准备阶段 2.1.推断 Web 应用类型 2.2.加载应用上下文初始器 ApplicationContextInitializer ...
随机推荐
- STL中的set和multiset
注意: 1.count() 常用来判断set中某元素是否存在,因为一个键值在set只可能出现0或1次. 2.erase()用法 erase(iterator) ,删除定位器iterator指向的值 ...
- Linux磁盘空间容量不够-通过新增磁盘-挂载原磁盘
首先上一张图 -------1)首先fdisk 一块磁盘并格式化 mkfs.ext4 /dev/sda15 --------2)将此磁盘挂载在mnt目录下,并将磁盘容量不够的磁盘所有文件进行复制到mn ...
- KVM在线扩展虚拟机内存
环境介绍 在KVM下有一台虚拟机内存不够需要扩展内存.宿主机地址是192.168.1.28.我需要扩展的虚拟机是centos1708vm03. 1.登陆上宿主机查看虚拟机配置 virsh dumpxm ...
- springmvc无法进入controller,且报错404
今天搭建一个springmvc项目时,前台一直报错404,在controller中调试发现程序没有进入controller. 通过多次刷新前台页面,发现第一次进入是会弹出错误提示,第二次之后就直接40 ...
- 关于Graph Convolutional Network的初步理解
为给之后关于图卷积网络的科研做知识积累,这里写一篇关于GCN基本理解的博客.GCN的本质是一个图网络中,特征信息的交互+与传播.这里的图指的不是图片,而是数据结构中的图,图卷积网络的应用非常广泛 ,经 ...
- TensorFlow开发者证书 中文手册
经过一个月的准备,终于通过了TensorFlow的开发者认证,由于官方的中文文档较少,为了方便大家了解这个考试,同时分享自己的备考经验,让大家少踩坑,我整理并制作了这个中文手册,请大家多多指正,有任何 ...
- akka-typed(6) - cluster:group router, cluster-load-balancing
先谈谈akka-typed的router actor.route 分pool router, group router两类.我们先看看pool-router的使用示范: val pool = Rout ...
- 君荣一卡通软件mysql转sqlserver 教程
Mysql数据库转sql数据库方法 注意:新建的SQL数据库一得先登录一次后再做迁移!!!!特别注意 如果客户以前安装的是mysql数据库,现在希望把mysql数据库转换的sql数据库,方法如下: 1 ...
- [PyQt5]文件对话框QFileDialog的使用
概述选取文件夹 QFileDialog.getExistingDirectory()选择文件 QFileDialog.getOpenFileName()选择多个文件 QFileDialog.getOp ...
- 小师妹学JVM之:JVM的架构和执行过程
目录 简介 JVM是一种标准 java程序的执行顺序 JVM的架构 类加载系统 运行时数据区域 执行引擎 总结 简介 JVM也叫Java Virtual Machine,它是java程序运行的基础,负 ...