SpringBoot入门(五)----- 启动类run方法都做了什么(上)

上一篇说了启动类注解@SpringBootApplication大致的作用,这篇文章主要对启动注解做一些了解,如果需要,可以点击超链接。

我们创建spingboot项目后,都会有一个启动类,里面有这样一行代码:
SpringApplication.run(DemoApplication.class,args)

他调用了SpringApplication的静态run方法。下面让我们简单看看它都做了什么
我们简单的跟了一下源码,下面是流程图:
在这里插入图片描述
先看它new了一个SpringApplication,调用了有参构造,构造方法如下:

    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 = new HashSet();
        this.isCustomEnvironment = false;
        this.lazyInitialization = false;
		// 设置一些资源加载器
        this.resourceLoader = resourceLoader;
		// 加载类资源不能为空
        Assert.notNull(primarySources, "PrimarySources must not be null");
		//  做一个数据结构的转换
        this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
		//  判断当前项目类型是什么
        this.webApplicationType = WebApplicationType.deduceFromClasspath();
		//  设置初始化器
        this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
		//  设置监听器,springfactories 想要寻找的话,就是通过spring.factory
        this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
		// 根据class 推断应用的入口类  通过run方法调用main方法
        this.mainApplicationClass = this.deduceMainApplicationClass();
    }

其主要的方法有两个:
WebApplicationType.deduceFromClasspath()
this.getSpringFactoriesInstances(ApplicationContextInitializer.class)

下面我们简单看一下这两个方法的作用:

WebApplicationType.deduceFromClasspath():

源码:

    static WebApplicationType deduceFromClasspath() {
        if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", (ClassLoader)null) && !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", (ClassLoader)null) && !ClassUtils.isPresent("org.glassfish.jersey.servlet.ServletContainer", (ClassLoader)null)) {
            return REACTIVE;
        } else {
            String[] var0 = SERVLET_INDICATOR_CLASSES;
            int var1 = var0.length;

            for(int var2 = 0; var2 < var1; ++var2) {
                String className = var0[var2];
                if (!ClassUtils.isPresent(className, (ClassLoader)null)) {
                    return NONE;
                }
            }

            return SERVLET;
        }
    }

通过代码我们可以看出,这个方法是判断了我们的工程到底是个什么类型(web工程,基本的spring工程等)

getSpringFactoriesInstances(ApplicationContextInitializer.class)

这个方法我们需要往里跟一下,上流程图
在这里插入图片描述
经过跟进了以下代码,看到了熟悉的META-INF/spring.factories,得知spring是在这时候把EnableAutoConfiguration注解配置的bean都注册进springioc容器里了
第一小节把新建对象干的事就大致说完了,下一篇说说run方法。

世界上有10种人,一种是懂二进制的,一种是不懂二进制的。

感谢您的收看,如有哪里写的不对 请留言,谢谢。

发布了71 篇原创文章 · 获赞 54 · 访问量 42万+

猜你喜欢

转载自blog.csdn.net/weixin_43326401/article/details/104077179