SpringBoot工作机制

SpringBoot工作机制

(原创内容,转载请注明来源,谢谢)

一、概述

Spring Boot是对于Spring框架“约定优于配置”理念的实践产物。

一个最简单的Spring Boot的启动类如下():

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
         public static voidmain(String[] args) {
                   SpringApplication.run(Application.class,args);
         }
}

编译上述代码,就可以启动一个Spring Boot项目。

二、@SpringBootApplication

该注解实质上是多个注解的组合,最重要的三个注解包括:@Configuration、@EnableAutoConfiguration、@ComponentScan。

将上述的SpringBoot启动类的@SpringBootApplication改成上述三个注解,项目也能正常启动,且效果功能对等。

1、@Configuration

@Configuration标记一个类是JavaConfig配置类,因此,上述标记将SpringBoot的启动类也标记为一个java config的IoC配置类。

实际上,启动类未必一定要设置成配置类,启动类更原生的写法如下:

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class StarterConfiguration{
@Bean
public Controller controller(){
return new Controller();
}
}
public class Application {
         public static voidmain(String[] args) {
                   SpringApplication.run(StarterConfiguration.class,args);
         }
}

该方式,即将启动类和IoC配置类完全分隔开。

2、@EnableAutoConfiguration

@Enable开头的注解,通常都是借助@Import注解的支持,收集和注册特定场景相关的bean定义。

该注解也是一个复合注解,其中最重要的一条为:@Import(EnableAutoConfigurationImportSelector.class),其帮助SpringBoot将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器中。

该注解能够实现将所有符合条件的配置都加载到IoC容器中,是借助于SpringFactoriesLoader类来实现的。

该类是Spring框架私有的扩展方案,主要功能是从指定的配置文件META-INF/spring.factories加载配置。spring.factories是一个典型的javaproperties文件,配置的格式是key=value格式,key和value都是java的完整的类名。

因此,@EnableAutoConfiguration的功能是,从classpath中搜寻所有的META-INF/spring.factories配置文件,并将其中对应的配置项通过反射,实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器,然后汇总并加载到一个IoC容器。

3、@ComponentScan

该注释的功能是,自动扫描并加载符合条件的组件或bean定义,最终将这些bean加载到容器中。

因此,如果没有bean定义需要通过该注解加载到当前SpringBoot的IoC容器中,则不需要该注解项目也可以正常启动。

三、SpringApplication

项目的main方法,是通过SpringApplication.run方法来实现启动的。SpringApplication将一个典型的Spring项目的启动模板化了。如果不需要修改启动流程,则直接使用此方式就可以启动项目。

1、SpringApplication执行流程

执行流程如下:

1)创建SpringApplication实例。

实例初始化的时候,会进行以下几个操作:

1. 根据classpath中是否存在某个特征类,来决定是创建web应用的ApplicationContext类型,还是创建一个Standalone的ApplicationContext。

2. 使用SpringFactoriesLoader在应用的classpath中,查找并加载所有可用的ApplicationContextInitializer。

3. 使用SpringFactoriesLoader在应用的classpath中,查找并加载所有可用的ApplicationListener。

4. 推断并设置main方法的定义类。

2)执行run方法逻辑。

首先,遍历执行所有通过SpringFactoriesLoader可以查找并加载的SpringApplicationRunListener,并调用其started()方法,告知其项目要开始执行。

3)创建并配置当前项目要使用的Environment,包括配置要使用的PropertySource以及Profile。

4)遍历调用所有SpringApplicationRunListener的environmentPrepared()方法,告知项目的环境准备好。

5)如果SpringApplication的showBanner属性设置成true,会在编译启动的console框内,展示出spring样式的banner。该功能纯粹为了乐趣。

6)根据配置决定创建什么类型的ApplicationContext,并将之前准备好的Environment配置给其使用。

7)ApplicationContext创建好后,SpringApplication再次借助SpringFactoriesLoader,查找并加载classpath中可用的ApplicationContextInitializer,并对创建好的ApplicationContext进行进一步处理。

8)遍历所有的SpringApplicationRunListener的contextPrepared()方法,告知ApplicationContext已经准备好。

9)将之前所有@EnableAutoConfiguration获取的所有配置和其他形式的IoC容器配置加载到已经准备完毕的ApplicationContext。

10)遍历所有的SpringApplicationRunListener的contextLoaded()方法,告知ApplicationContext装载完毕。

11)调用ApplicationContext的refresh()方法。

12)查找当前ApplicationContext是否有注册CommandLineRunner,如果有则执行(无论是手动注册还是自动扫描的,都会执行)。

13)遍历所有的SpringApplicationRunListener的finished(),表示启动完毕。如果启动失败也会调用该方法,并且会将异常信息一并传入处理。

流程如下:

——written by linhxx 2017.09.22

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-09-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏向治洪

android-async-http详解

android-async-http开源项目可以是我们轻松的获取网络数据或者向服务器发送数据,使用起来非常简单,关于android-async-http开源项...

1746
来自专栏企鹅号快讯

前端开发人员如何搭建数据库

问题:我怎么才能收到你们公众号平台的推送文章呢? ? 最近有人问我,前端开发人员要存储用户数据,最简单的方法是什么。现在仅关于这部分,我来说明下怎么做。 搭建数...

20910
来自专栏我和PYTHON有个约会

Django来敲门~第一部分【5.1.项目配置settings.py详解】

我们创建好了一个Python项目(mysite/)之后,需要在项目中添加模块应用(polls/),在模块应用中添加处理功能逻辑,如添加模块中的视图处理函数(po...

583
来自专栏个人随笔

Java日志记录--log4j and logback

1374
来自专栏技术小讲堂

iBatis.Net(2):基本概念与配置

写完第一篇,有朋友给我发邮件,说想让我配合实例写会不会更好一些,可是呢,我觉得这就相当于那些北大的什么鸟给无辜的孩子们吃快餐一样,我是坚决反对那样的,知其然不知...

2697
来自专栏一个会写诗的程序员的博客

《Springboot极简教程》问题解决:Springboot启动报错 Whitelabel Error Page: This application has no explicit mapping

首先,这个出错页面是SpringBoot的一个默认出错页面。源码在:org.springframework.boot.autoconfigure.web.ser...

585
来自专栏菩提树下的杨过

ZooKeeper 笔记(5) ACL(Access Control List)访问控制列表

zk做为分布式架构中的重要中间件,通常会在上面以节点的方式存储一些关键信息,默认情况下,所有应用都可以读写任何节点,在复杂的应用中,这不太安全,ZK通过ACL机...

4726
来自专栏流柯技术学院

python日志模块---logging

默认情况下,logging将日志打印到屏幕,日志级别为WARNING; 日志级别大小关系为:CRITICAL > ERROR > WARNING > INFO ...

592
来自专栏开发与安全

gdb基础命令和常用操作补充

GDB是Unix下的一个程序调试工具,类似于windows下面的VC调试器,区别在于GDB采用全命令行控制。 使用GDB需要在编译时使用-g选项,gcc支持-...

2140
来自专栏dotnet core相关

WCF 入门 (18)

这集的中心意思是WCF服务如果有异常,应该throw出来fault exception,而不是简单的默认的.net 的异常。

523

扫描关注云+社区