智能摘要文章源自JAVA秀-https://www.javaxiu.com/30321.html
SpringFactoriesLoader其主要功能就是从指定的配置文件META-INF/spring.factories加载配置。/设置监听器,从"META-INF/spring.factories"读取ApplicationListener类的实例名称集合并去重,并进行set去重。文章源自JAVA秀-https://www.javaxiu.com/30321.html
原文约 1215 字 | 图片 1 张 | 建议阅读 3 分钟 | 评价反馈文章源自JAVA秀-https://www.javaxiu.com/30321.html
spring boot 启动流程,spring boot 启动类介绍
文章源自JAVA秀-https://www.javaxiu.com/30321.html 维维悄悄写代码文章源自JAVA秀-https://www.javaxiu.com/30321.html 简书作者文章源自JAVA秀-https://www.javaxiu.com/30321.html
0.2732021-05-29 00:47打开App文章源自JAVA秀-https://www.javaxiu.com/30321.html
spring boot 启动类介绍
- spring boot项目启动类代码
@SpringBootApplication public class Application{ public static void main(String[] args) { SpringApplication.run(SystemApplication.class,args); } }
静态方法run(),是spring boot项目的启动入口文章源自JAVA秀-https://www.javaxiu.com/30321.html
- SpringBootApplication注解
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} ) public @interface SpringBootApplication {}
- SpringApplication.run()
- @SpringBootConfiguration内部用的也是@Configuration,它是javaConfig形式的Spring Ioc容器的配置类。
- @EnableAutoConfiguration
@SuppressWarnings("deprecation") @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(EnableAutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration {}
借助@Import的支持,注册bean。@Import(EnableAutoConfigurationImportSelector.class)借助EnableAutoConfigurationImportSelector类,帮助springboot应用将所有符合条件的@Configuration配置都加载到Ioc容器,借助SpringFactoriesLoader工具类实现自动配置文章源自JAVA秀-https://www.javaxiu.com/30321.html
- SpringFactoriesLoader其主要功能就是从指定的配置文件META-INF/spring.factories加载配置。将其中org.springframework.boot.autoconfigure.EnableutoConfiguration对应的配置项通过反射(Java Refletion)实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器。
Spring Boot启动流程
- 运行springboot启动类
- 执行SpringApplication.run()方法
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) { return run(new Class[]{primarySource}, args); } public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) { return (new SpringApplication(primarySources)).run(args); }
- SpringApplication.run()静态方法最终创建了一个SpringApplication对象,运行了其中的run方法
- SpringApplication的构造方法设置基础值
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.sources = new LinkedHashSet(); this.bannerMode = Mode.CONSOLE; this.logStartupInfo = true; this.addCommandLineProperties = true; this.addConversionService = true; this.headless = true; this.registerShutdownHook = true; this.additionalProfiles = new HashSet(); this.isCustomEnvironment = false; this.lazyInitialization = false; //资源初始化加载器,默认null this.resourceLoader = resourceLoader; //断言主要加载资源类不能为null,否则报错 Assert.notNull(primarySources, "PrimarySources must not be null"); //初始化主要加载资源类集合并去重 this.primarySources = new LinkedHashSet(Arrays.asList(primarySources)); //判断当前WEB 应用类型,三种类型:NONE非web项目,SERVLET servlet web项目,REACTIVE 响应式web项目 this.webApplicationType = WebApplicationType.deduceFromClasspath(); //设置应用上下文初始化器,从"MATE-INFO/spring.factories"读取 ApplicationContextInitializer类的实例名称集合并去重,并进行set去重。(一共7个) this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class)); //设置监听器,从"META-INF/spring.factories"读取ApplicationListener类的实例名称集合并去重,并进行set去重。(一共11个) this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class)); //推断主入口应用类,通过当前调用栈,获取Main方法所在类,并赋值给mainApplicationClass this.mainApplicationClass = this.deduceMainApplicationClass(); }
public ConfigurableApplicationContext run(String... args) { //1、创建并启动计时监控类 StopWatch stopWatch = new StopWatch(); stopWatch.start(); //2、初始化应用上下文和异常报告集合 ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>(); //3、设置系统属性“java.awt.headless”的值,默认为true,用于运行headless服务器,进行简单的图像处理,多用于在缺少显示屏、键盘或者鼠标时的系统配置,很多监控工具如jconsole 需要将该值设置为true configureHeadlessProperty(); //4、创建所有spring运行监听器并发布应用启动事件,简单说的话就是获取SpringApplicationRunListener类型的实例(EventPublishingRunListener对象),并封装进SpringApplicationRunListeners对象,然后返回这个SpringApplicationRunListeners对象。说的再简单点,getRunListeners就是准备好了运行时监听器EventPublishingRunListener。 SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(); try { //5、初始化默认应用参数类 ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); //6、根据运行监听器和应用参数来准备spring环境 ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); //将要忽略的bean的参数打开 configureIgnoreBeanInfo(environment); //7、创建banner打印类 Banner printedBanner = printBanner(environment); //8、创建应用上下文,可以理解为创建一个容器 context = createApplicationContext(); //9、准备异常报告器,用来支持报告关于启动的错误 exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context); //10、准备应用上下文,该步骤包含一个非常关键的操作,将启动类注入容器,为后续开启自动化提供基础 prepareContext(context, environment, listeners, applicationArguments, printedBanner); //11、刷新应用上下文 refreshContext(context); //12、应用上下文刷新后置处理,做一些扩展功能 afterRefresh(context, applicationArguments); //13、停止计时监控类 stopWatch.stop(); //14、输出日志记录执行主类名、时间信息 if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch); } //15、发布应用上下文启动监听事件 listeners.started(context); //16、执行所有的Runner运行器 callRunners(context, applicationArguments); }catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, listeners); throw new IllegalStateException(ex); } try { //17、发布应用上下文就绪事件 listeners.running(context); }catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, null); throw new IllegalStateException(ex); } //18、返回应用上下文 return context; }
文章源自JAVA秀-https://www.javaxiu.com/30321.html© 著作权归作者所有,转载或内容合作请联系作者 文章源自JAVA秀-https://www.javaxiu.com/30321.html

评论