• SpringBoot源码解析:创建SpringApplication对象实例


    上篇文章SpringBoot自动装配原理解析中,我们分析了SpringBoot的自动装配原理以及@SpringBootApplication注解的原理,本篇文章则继续基于上篇文章中的main方法来分析SpringApplication这个类

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

    点击run方法一路跟踪下来,发现首先做的是实例化SpringApplication对象实例

    public static ConfigurableApplicationContext run(Class<?> primarySource,
    			String... args) {
    		return run(new Class<?>[] { primarySource }, args);
    	}
    	public static ConfigurableApplicationContext run(Class<?>[] primarySources,
    			String[] args) {
    		return new SpringApplication(primarySources).run(args);
    	}
    	public SpringApplication(Class<?>... primarySources) {
    		this(null, primarySources);
    	}
    public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    		this.resourceLoader = resourceLoader;
    		Assert.notNull(primarySources, "PrimarySources must not be null");
    		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    		this.webApplicationType = deduceWebApplicationType();
    		setInitializers((Collection) getSpringFactoriesInstances(
    				ApplicationContextInitializer.class));
    		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    		this.mainApplicationClass = deduceMainApplicationClass();
    	}
    
    1. 首先看一下deduceWebApplicationType方法
    private WebApplicationType deduceWebApplicationType() {
            if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", (ClassLoader)null) && !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", (ClassLoader)null)) {
                return WebApplicationType.REACTIVE;
            } 
            for (String className : "javax.servlet.Servlet", org.springframework.web.context.ConfigurableWebApplicationContext") {
    			if (!ClassUtils.isPresent(className, null)) {
    				return WebApplicationType.NONE;
    			}
    	}
              return WebApplicationType.SERVLET;
            }
        }
    

    大抵意思就是根据当前项目中是否存在上方的几个类来推断出当前的web环境,这里因为SpringBoot默认使用的web框架是SpringMVC,所以最后返回结果为WebApplicationType.SERVLET

    1. 加载所有的ApplicationContextInitializerApplicationListener的实现类
     private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
            List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
            AnnotationAwareOrderComparator.sort(instances);
            return instances;
        }
    

    可以看到主要还是用的SpringFactoriesLoader这个类去加载这两个接口的实现类,加载到类以后使用反射的方式构造出这些类的实例,然后根据这些实现类上的Order注解的值进行排序

    关于这些实现类的具体作用请关注后续的文章

    1. 最后一行的意义是找到入口方法main所在的类,赋值给全局变量mainApplicationClass
  • 相关阅读:
    js——h5如何直接唤起百度地图app进行导航
    flutter学习之路-window下安装
    mongoDB- window下安装与启动
    js-轻松理解map, reduce, filter ,every, some
    js基础-构造函数
    js基础-node环境下说哈js异步,同步,单线程,微任务和宏任务
    js基础-作用域和作用域链以及闭包
    wamp安装
    php tp5 连接sqlserver配置
    php curl扩展
  • 原文地址:https://www.cnblogs.com/zhixiang-org-cn/p/11569994.html
Copyright © 2020-2023  润新知