概述
版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/>
</parent>
启动入口代码
package com.ybjdw.tool;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.util.unit.DataSize;
import javax.servlet.MultipartConfigElement;
import java.io.File;
@EnableAsync
@SpringBootApplication
@MapperScan("com.ybjdw.tool.*.dao")
public class ToolApplication {
@Value("${log.custom.dir}")
private String logCustomDir;
public static void main(String[] args) {
SpringApplication.run(ToolApplication.class, args);
}
// 上传相关
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
String location = logCustomDir + "/uploadFileTmp"; // 设置上传临时文件存储位置
File file = new File(location);
if(!file.exists()){
file.mkdirs();
}
factory.setLocation(location);
// 允许上传的文件最大值.
factory.setMaxFileSize(DataSize.ofMegabytes(100));
// 设置总上传数据大小
factory.setMaxRequestSize(DataSize.ofMegabytes(200));
return factory.createMultipartConfig();
}
}
启动步骤
根据SpringApplication的官方描述,可以得到启动步骤如下:
1.根据classpath创建适当的应用上下文
Create an appropriate ApplicationContext depending on your classpath
2.注册CommandLinePropertySource来暴露命令行参数作为spring的属性
Register a CommandLinePropertySource to expose command line arguments as Spring properties
3.刷新应用上下文,加载所有的单例bean
Refresh the application context,loading all singleton beans
4.触发所有的CommandLineRunner实例
Trigger any CommandLineRunner beans
2.1Spring加载bean的方式及主应用类确定
Spring加载bean有四种方式:
通过完全限定类名加载,使用AnnotatedBeanDefinitionReader。
通过XML加载,使用XmlBeanDefinitionReader
通过groovy script加载,使用GroovyBeanDefinitionReader
通过扫描包加载,使用ClassPathBeanDefinitionScanner
官方推荐使用第一种方式加载,同时下面为应用如何推测启动类的:通过遍历运行时栈跟踪集合,找到方法名为main的类,这就是为什么我们没指定启动类,但应用却知道,体现了约定优于配置的思想。
2.2根据classpath创建适当的应用上下文
先根据classpath推断当前WebApplicationType。
根据WebApplicationType创建合适的应用上下文。
2.3注册CommandLinePropertySource来暴露命令行参数作为spring的属性
先通过SimpleCommandLinePropertySource解析命令行参数args,并将它注册为CommandLinePropertySource(名称为【commandLineArgs】,value为包含命令行参数的CommandLineArgs)。
其中COMMAND_LINE_PROPERTY_SOURCE_NAME常量名称是commandLineArgs
同时也会将applicationArguments注册到beanFactory,名称为springApplicationArguments。
2.4刷新应用上下文,加载所有的单例bean
在SpringApplication的run方法中有调用刷新上下文的方法。
最后调用ConfigurableApplicationContext的refresh方法。
ConfigurableApplicationContext接口根据环境有三个不同的实现类。
当前使用的是AbstractApplicationContext的refresh方法。