深入理解SpringBoot(一)----SpringBoot的启动流程分析

1、SpringApplication 对象实例化

SpringApplication 文件

public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
      // 传递的source其实就是类Bootstrap
    return new SpringApplication(sources).run(args);
    // 实例化一个SpringApplication对象执行run方法
}

实例化的时候又会执行initialize 方法

private void initialize(Object[] sources) {
      // 这个source依旧是上文说的Bootstrap.class 类
    if (sources != null && sources.length > 0) {
        this.sources.addAll(Arrays.asList(sources));
        // 添加到source资源列表里面去
    }
    this.webEnvironment = deduceWebEnvironment();
    // 设置其是否为web环境
    setInitializers((Collection) getSpringFactoriesInstances(
            ApplicationContextInitializer.class));
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    // 拆分为两步,一步是getSpringFactoriesInstances,再者就是set操作
    // set操作很简单,就是设置当前对象的初始化对象以及监听器
    this.mainApplicationClass = deduceMainApplicationClass();
    // 通过堆栈信息,推断 main方法的类对象为当前的主程序类
}

private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet",
            "org.springframework.web.context.ConfigurableWebApplicationContext" };

private boolean deduceWebEnvironment() {
    for (String className : WEB_ENVIRONMENT_CLASSES) {
           // 遍历包含上述两个类名称的数组
        if (!ClassUtils.isPresent(className, null)) {
               // 一旦发现不存在该类,就立即返回 deduce 推断不是web环境
            return false;
        }
    }
    // 必须同时包含两个类,才推断出为web环境
    return true;
}

getSpringFactoriesInstances 方法操作

private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,
        Class<?>[] parameterTypes, Object... args) {
        // 传递的type就是上面说的ApplicationContextInitializer.class以及ApplicationListener.class类
        // 类型以及参数目前都没有具体指
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    // Use names and ensure unique to protect against duplicates
    Set<String> names = new LinkedHashSet<String>(
            SpringFactoriesLoader.loadFactoryNames(type, classLoader));
            // 通过SpringFactoriesLoader 获取对应的名称,具体详情可以看下面的代码块
            // 这点需要重点关注下!!!
            // 结果就是返回一个set集合
    List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
            classLoader, args, names);
            // 看样子就是创建一个实例的集合
    AnnotationAwareOrderComparator.sort(instances);
    // 然后通过AnnotationAwareOrderComparator 的排序规则跪实例集合进行排序
    // 排序就是看是否存在Order或者Priority注解,然后取得注解的值,排在集合前面
    return instances;
}

private <T> List<T> createSpringFactoriesInstances(Class<T> type,
        Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args,
        Set<String> names) {
    List<T> instances = new ArrayList<T>(names.size());
    for (String name : names) {
           // 遍历上面取到的name 集合
        try {
            Class<?> instanceClass = ClassUtils.forName(name, classLoader);
            // 取到这个类名称的类
            Assert.is
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

武昌库里写JAVA

您的鼓励将是我前进的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值