前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >一、ApplicationContext

一、ApplicationContext

原创
作者头像
用户10865967
修改2024-10-20 11:04:11
修改2024-10-20 11:04:11
10000
代码可运行
举报
运行总次数:0
代码可运行

(一)Applicaiont 继承关系解读

ApplicationContext 继承关系
ApplicationContext 继承关系

ApplicationContext 分别继承了以下接口:

ResourcePatternResolver:解析和加载资源

MessageSource:国际化

BeanFactory:Bean 容器

EnvironmentCapable:获取应用环境配置

ApplicationEventPublisher:发布事件

(二)构建ApplicationContext 对象

代码语言:javascript
代码运行次数:0
复制
@SpringBootApplication
public class SpringSourceCodeTestApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext springBootContext = SpringApplication.run(SpringSourceCodeTestApplication.class, args);
    }

}

(三)SpringApplication.run

run 方法向下追溯可以追溯到org.springframework.boot.SpringApplication#run(java.lang.Class<?>[], java.lang.String[])方法,该方法可以分为两个步骤,第一个步骤为创建SpringApplication对象,第二个步骤为基于该对象调用run方法

代码语言:javascript
代码运行次数:0
复制
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
    return (new SpringApplication(primarySources)).run(args);
}

(四)创建SpringApplication对象

创建SpringApplication对象可以分为以下几步:

1. 使用常量值初始化一些字段

2. 设置主类

3. 推断web应用类型

4. 从代码目录和jar包目录下的META-INF/spring.factories文件中加载key为org.springframework.boot.BootstrapRegistryInitializer的values,并基于这些values对应的类创建对象保存到

bootstrapRegistryInitializers容器中

5. 从代码目录和jar包目录下的META-INF/spring.factories文件中加载key为org.springframework.context.ApplicationContextInitializer的values,并基于这些values对应的类创建对象保存到listeners容器中

6. 从代码目录和jar包目录下的META-INF/spring.factories文件中加载key为org.springframework.context.ApplicationListener的values,并基于这些values对应的类创建对象保存到initializers 容器中

7. 基于当前的栈查找main 方法所属的类,基于该类创建实例并赋值给mainApplicationClass

代码语言:javascript
代码运行次数:0
复制
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 = Collections.emptySet();
    this.isCustomEnvironment = false;
    this.lazyInitialization = false;
    this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
    this.applicationStartup = ApplicationStartup.DEFAULT;
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "PrimarySources must not be null");
    this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
    this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = this.deduceMainApplicationClass();
}

(五)org.springframework.boot.SpringApplication#run(java.lang.String...)

run方法可以分为以下几步:

1. 创建一个bootStrapContext容器,并基于initializers中的initializer回调初始化

2. 配置java.awt.headless属性

3. 构建事件发布器:从代码目录和jar包目录下的META-INF/spring.factories文件中加载key为org.springframework.boot.SpringApplicationRunListener的values,并基于这些values对应的类创建对象保存到

SpringApplicationRunListeners对象中

4. 使用事件发布器发布容器启动事件

5. 设置应用环境配置

6. 打印Banner

7. 创建context实例

8. 准备容器

9. 刷新容器

10. 容器后处理

11. 发布容器已启动事件

代码语言:javascript
代码运行次数:0
复制
public ConfigurableApplicationContext run(String... args) {
    long startTime = System.nanoTime();
    DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
    ConfigurableApplicationContext context = null;
    this.configureHeadlessProperty();
    SpringApplicationRunListeners listeners = this.getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);

    Throwable ex;
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        this.configureIgnoreBeanInfo(environment);
        Banner printedBanner = this.printBanner(environment);
        context = this.createApplicationContext();
        context.setApplicationStartup(this.applicationStartup);
        this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
        this.refreshContext(context);
        this.afterRefresh(context, applicationArguments);
        Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
        if (this.logStartupInfo) {
            (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);
        }

        listeners.started(context, timeTakenToStartup);
        this.callRunners(context, applicationArguments);
    } catch (Throwable var12) {
        ex = var12;
        this.handleRunFailure(context, ex, listeners);
        throw new IllegalStateException(ex);
    }

    try {
        Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
        listeners.ready(context, timeTakenToReady);
        return context;
    } catch (Throwable var11) {
        ex = var11;
        this.handleRunFailure(context, ex, (SpringApplicationRunListeners)null);
        throw new IllegalStateException(ex);
    }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • (一)Applicaiont 继承关系解读
  • (二)构建ApplicationContext 对象
  • (三)SpringApplication.run
  • (四)创建SpringApplication对象
  • (五)org.springframework.boot.SpringApplication#run(java.lang.String...)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档