spring boot 之application

SpringApplication 准备阶段

配置 Spring Boot Bean 源


通过 Java 配置 Class 或 XML 上下文配置文件集合,用于 Spring Boot  BeanDefinitionLoader 读取 ,并且将配置源解析加载为
Spring Bean 定义

推断 Web 应用类型


根据当前应用 ClassPath 中是否存在相关实现类来推断 Web 应用的类型,包括:

Web Reactive: WebApplicationType.REACTIVE
Web Servlet: WebApplicationType.SERVLET
非 Web: WebApplicationType.NONE

//参考 org.springframework.boot.SpringApplication#deduceWebApplicationType
private WebApplicationType deduceWebApplicationType() {
if (ClassUtils.isPresent(REACTIVE_WEB_ENVIRONMENT_CLASS, null)
&& !ClassUtils.isPresent(MVC_WEB_ENVIRONMENT_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
for (String className : WEB_ENVIRONMENT_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
return WebApplicationType.SERVLET;
}

推断引导类(Main Class)

根据 Main 线程执行堆栈判断实际的引导类

//参考方法: org.springframework.boot.SpringApplication#deduceMainApplicationClass
private Class<?> deduceMainApplicationClass() {
        try {
            StackTraceElement[] stackTrace = (new RuntimeException()).getStackTrace();
            StackTraceElement[] var2 = stackTrace;
            int var3 = stackTrace.length;

            for(int var4 = 0; var4 < var3; ++var4) {
                StackTraceElement stackTraceElement = var2[var4];
                if ("main".equals(stackTraceElement.getMethodName())) {
                    return Class.forName(stackTraceElement.getClassName());
                }
            }
        } catch (ClassNotFoundException var6) {
        }

        return null;
    }

加载应用上下文初始器 ( ApplicationContextInitializer )

利用 Spring 工厂加载机制,实例化  ApplicationContextInitializer 实现类,并排序对象集合。说白了就是从spring.factories配置文件中读取org.springframework.context.ApplicationContextInitializer属性。

//参考  org.springframework.boot.SpringApplication#deduceMainApplicationClass
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String> names = new LinkedHashSet<>(
//重点在这个方法
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names);
//并进行排序
AnnotationAwareOrderComparator.sort(instances);
return instances;
}

核心实现就是利用 SpringFactoriesLoader 到META-INF/spring.factories中去加载资源,并将读取到的实例进行创建并排序。

加载应用事件监听器( ApplicationListener )

利用 Spring 工厂加载机制,实例化  ApplicationListener 实现类,并排序对象集合,因为其与上文初始化的加载一致,所以略过。

SpringApplication 运行阶段

加载 SpringApplication 运行监听器( SpringApplicationRunListeners )

利用 Spring 工厂加载机制,读取  SpringApplicationRunListener 对象集合,并且封装到组合类
SpringApplicationRunListeners

默认全局只有一个

# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener

运行 SpringApplication 运行监听器( SpringApplicationRunListeners )

public interface SpringApplicationRunListener {
    //Spring 应用刚启动 
    void starting();
    //ConfigurableEnvironment 准备妥当,允许将其调整 
    void environmentPrepared(ConfigurableEnvironment environment);
    //ConfigurableApplicationContext 准备妥当,允许将其调整 
    void contextPrepared(ConfigurableApplicationContext context);
    //ConfigurableApplicationContext 已装载,但仍未启动 
    void contextLoaded(ConfigurableApplicationContext context);
    //ConfigurableApplicationContext 已启动,此时 Spring Bean 已初始化完成 
    void started(ConfigurableApplicationContext context);
    //Spring 应用正在运行 
    void running(ConfigurableApplicationContext context);
    //Spring 应用运行失败 
    void failed(ConfigurableApplicationContext context, Throwable exception);
}

创建 Spring 应用上下文( ConfigurableApplicationContext )

//根据准备阶段的推断 Web 应用类型创建对应的  ConfigurableApplicationContext 实例:
//Web Reactive: 
AnnotationConfigReactiveWebServerApplicationContext
//Web Servlet: 
AnnotationConfigServletWebServerApplicationContext
//非 Web: 
AnnotationConfigApplicationContext

创建 Environment

 

根据准备阶段的推断 Web 应用类型创建对应的  ConfigurableEnvironment 实例:
Web Reactive: StandardEnvironment
Web Servlet: StandardServletEnvironment
非 Web: StandardEnvironment

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值