SpringApplication

一、场景

SpringApplication一般作为Springboot项目中的引导启动类。调用静态方法run()即可执行,我们自己项目中的启动类;

如下代码,即通过SpringApplication引导启动ShardingDbReadWriteApplication

@SpringBootApplication
public class ShardingDbReadWriteApplication {
   public static void main(String[] args) {
      SpringApplication.run(ShardingDbReadWriteApplication.class, args);
   }
}

二、类属性图

spring controller 入口前执行_监听器

Banner相关属性:

primarySources

可以通过SpringApplication构造方法传入,也可以通过spring.main.sources配置。

banner 横幅/标语

spring controller 入口前执行_监听器_02

这个是Spring默认的banner。

自定义bannner

如下代码即可自定义banner

SpringApplication springApplication = new SpringApplication(ShardingDbReadWriteApplication.class);
springApplication.setBanner(new Banner() {
    @Override
    public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {
        out.println("hello girl!");
    }
});

效果如下:

spring controller 入口前执行_监听器_03

bannerMode

支持三种模式:

Banner.Mode.LOG   banner打印在日志中
Banner.Mode.CONSOLE    bannner打印在控制台
Banner.Mode.OFF   bannner不打印

监听器:

SpringApplication有自己的生命周期,在生命周期每个环节,都会发送Event事件。而Spring系统提供了事件监听以及自定义事件处理器的能力。

listeners属性存储了所有实现ApplicationListener接口的时间监听器

自定义监听器

当然我们也可以定义监听器,方法如下,其中SelfDefineListener类,就是我们自己实现了ApplicationListener的监听器

public class SelfDefineListener implements ApplicationListener {
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationStartingEvent) {
            System.out.println("[SelfDefineListener] ApplicationStartingEvent!!!!!!!!!!!!!!!!!!!!");
        }
        else if (event instanceof ApplicationEnvironmentPreparedEvent) {
            System.out.println("[SelfDefineListener] ApplicationEnvironmentPreparedEvent!!!!!!!!!!!!!!!!!!!!");
        }
        else if (event instanceof ApplicationPreparedEvent) {
            System.out.println("[SelfDefineListener] ApplicationPreparedEvent!!!!!!!!!!!!!!!!!!!!");
        }
    }
}

在springApplication类中添加SelfDefineListener监听器实例

springApplication.addListeners(new SelfDefineListener());
运行效果:

spring controller 入口前执行_初始化_04

初始化器:

初始化器是ApplicationContextInitializer接口的实现类

setInitializers

初始化器的执行时机,是在ApplicationContext创建完成后,刷新(refreshContext)前执行的。

当前系统会预置一些初始化器,详见如下:

DelegatingApplicationContextInitializer
ContextIdApplicationContextInitializer:给context生成id
ConfigurationWarningsApplicationContextInitializer:给context添加配置警告后处理器
ServerPortInfoApplicationContextInitializer
SharedMetadataReaderFactoryContextInitializer
ConditionEvaluationReportLoggingListener

三、方法

Run方法的定位

白话一下Run方法的作用:

将业务定义的Application作为参数,实例化一个SpringApplication对象,通过SpringApplication的run方法,创建一个ApplicationContext,然后扫描业务工程对应的classpath,加载所有通过注解,xml等方式定义的bean,并将bean都实例化完成后,存储在BeanFactory中。这样业务运行过程中,需要哪些bean直接从BeanFactory中拿即可。

源码走读:

spring controller 入口前执行_java_05

挑选因为ApplicationContext作为Spring管理Bean的主要模型,所以挑选和ApplicationContext密切相关的步骤简单说下,详细流程后面章节单独展开分析。

createApplicationContex

主要是创建一个ApplicationContext。

prepareContext

执行一下系统中所有初始化器(ApplicationContextInitializer)的初始化操作。之后将Listenner添加到Context,因为Context有自己的生命周期,在生命周期中要调用Listener去处理监听后处理逻辑

refreshContext(context);

ApplicationContext维护了整个Spring项目的Bean,refreshContext就是在Spring启动过程中最重要的一步,扫描到系统中所有要加载的Bean,然后解析Bean之间的依赖,最后实例化Bean存储在BeanFactory中。供后续业务使用

afterRefresh(context, applicationArguments);

Spring提供了ApplicationContext加载完成后的回调接口。我们可以实现ApplicationRunner,CommandLineRunner接口去自定义处理我们的内容。