基础16-启动过程

启动流程:初始化

1、SpringApplication.run(SpringBootMainApplication.class, args);

2、(new SpringApplication(primarySources)).run(args);

3、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));

        this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));

        this.mainApplicationClass = this.deduceMainApplicationClass();

    }

WebApplicationType.deduceFromClasspath()用来判断DispatcherHandler、DispatcherServlet、ServletContainer是否是web应用;

getSpringFactoriesInstances(ApplicationContextInitializer.class)从META-INF/spring.factories文件中筛选出ApplicationContextInitializer列表;

getSpringFactoriesInstances(ApplicationListener.class)从this.getSpringFactoriesInstances中筛选出ApplicationListener列表;

deduceMainApplicationClass()则查找带有main方法的类;

(关键方法是:SpringFactoriesLoader.loadSpringFactories,且spring.factories都放在Map<String, List<String>>中)

启动流程:启动

public ConfigurableApplicationContext run(String... args) {

        StopWatch stopWatch = new StopWatch();

        stopWatch.start();

        ConfigurableApplicationContext context = null;

        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();

        this.configureHeadlessProperty();

        SpringApplicationRunListeners listeners = this.getRunListeners(args);

        listeners.starting();

        Collection exceptionReporters;

        try {

            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);

            this.configureIgnoreBeanInfo(environment);

            Banner printedBanner = this.printBanner(environment);

            context = this.createApplicationContext();

            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);

            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);

            this.refreshContext(context);

            this.afterRefresh(context, applicationArguments);

            stopWatch.stop();

            if (this.logStartupInfo) {

                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);

            }

            listeners.started(context);

            this.callRunners(context, applicationArguments);

        } catch (Throwable var10) {

            this.handleRunFailure(context, var10, exceptionReporters, listeners);

            throw new IllegalStateException(var10);

        }

        try {

            listeners.running(context);

            return context;

        } catch (Throwable var9) {

            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);

            throw new IllegalStateException(var9);

        }

    }

this.getRunListeners还是把从META-INF/spring.factories中读取到的SpringApplicationRunListener列表取出来;

listeners.starting则是遍历SpringApplicationRunListener列表,并调用其starting()方法;

this.prepareEnvironment就是创建各种Environment对象,下面是关键代码:

private ConfigurableEnvironment getOrCreateEnvironment() {
    if (this.environment != null) {
        return this.environment;
    } else {
        switch(this.webApplicationType) {
        case SERVLET:
            return new StandardServletEnvironment();
        case REACTIVE:
            return new StandardReactiveWebEnvironment();
        default:
            return new StandardEnvironment();
        }
    }
}

createApplicationContext则是根据类型不同,创建对应的Context对象,下面是关键代码:

protected ConfigurableApplicationContext createApplicationContext() {

        Class<?> contextClass = this.applicationContextClass;

        if (contextClass == null) {

            try {

                switch(this.webApplicationType) {

                case SERVLET:

                    contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");

                    break;

                case REACTIVE:

                    contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");

                    break;

                default:

                    contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");

                }

            } catch (ClassNotFoundException var3) {

                throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);

            }

        }

 

        return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);

    }

prepareContext方法分别调用了applyInitializers、contextPrepared、contextLoaded方法,来分别对initializer、listener进行初始化:

protected void applyInitializers(ConfigurableApplicationContext context) {

        Iterator var2 = this.getInitializers().iterator();

        while(var2.hasNext()) {

            ApplicationContextInitializer initializer = (ApplicationContextInitializer)var2.next();

            Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), ApplicationContextInitializer.class);

            Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");

            initializer.initialize(context);

        }

}

 

void contextPrepared(ConfigurableApplicationContext context) {

        Iterator var2 = this.listeners.iterator();

        while(var2.hasNext()) {

            SpringApplicationRunListener listener = (SpringApplicationRunListener)var2.next();

            listener.contextPrepared(context);

        }

}

 

void contextLoaded(ConfigurableApplicationContext context) {

        Iterator var2 = this.listeners.iterator();

        while(var2.hasNext()) {

            SpringApplicationRunListener listener = (SpringApplicationRunListener)var2.next();

            listener.contextLoaded(context);

        }

    }

refreshContext关键代码如下,负责对IOC容器中的Bean等一系列组件进行初始化,这里才是Bean等初始化的地方:

public void refresh() throws BeansException, IllegalStateException {

        synchronized(this.startupShutdownMonitor) {

            this.prepareRefresh();

            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

            this.prepareBeanFactory(beanFactory);

            try {

                this.postProcessBeanFactory(beanFactory);

                this.invokeBeanFactoryPostProcessors(beanFactory);

                this.registerBeanPostProcessors(beanFactory);

                this.initMessageSource();

                this.initApplicationEventMulticaster();

                this.onRefresh();

                this.registerListeners();

                this.finishBeanFactoryInitialization(beanFactory);

                this.finishRefresh();

            } catch (BeansException var9) {

                if (this.logger.isWarnEnabled()) {

                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);

                }

                this.destroyBeans();

                this.cancelRefresh(var9);

                throw var9;

            } finally {

                this.resetCommonCaches();

            }

        }

    }

started(context)与running(context)都是遍历SpringApplicationRunListener,然后分别调用其started、running方法:

void started(ConfigurableApplicationContext context) {

        Iterator var2 = this.listeners.iterator();

        while(var2.hasNext()) {

            SpringApplicationRunListener listener = (SpringApplicationRunListener)var2.next();

            listener.started(context);

        }

}

 

void running(ConfigurableApplicationContext context) {

        Iterator var2 = this.listeners.iterator();

        while(var2.hasNext()) {

            SpringApplicationRunListener listener = (SpringApplicationRunListener)var2.next();

            listener.running(context);

        }

 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
U-boot是一个开放源代码的引导加载程序,它是嵌入式Linux系统中非常重要的一部分。它主要负责完成硬件初始化、文件系统加载、内核启动、DTB传递等工作。下面是U-boot启动过程的详细分析: 1. 通电启动 当开关通电时,处理器会执行引导ROM中的启动代码。 2. 初始化寄存器 在进入U-boot之前,系统所有的寄存器都是未初始化的。U-boot要负责初始化CPU的所有寄存器,以确保所有设备都能正常工作。 3. 读取U-boot U-boot位于NOR或NAND闪存器中。为了读取U-boot,首先必须确定闪存器的类型和接口。当读取闪存器中的第一个块(一般是U-boot头)时,U-boot校验它的合法性,包括校验和、magic number、版本号等。如果校验失败,U-boot将停止执行。 4. 解压缩U-boot 如果U-boot被压缩了,那么需要用解压缩算法对其进行解压缩。在这个过程中,需要注意解压缩的起始地址和大小。 5. 设置环境变量 U-boot提供了一些环境变量,可以用来配置系统参数,例如:IP地址、MAC地址等。在这一步骤中,U-boot会将环境变量加载到DRAM中进行管理。同时,也可以通过TFTP、NFS等方式从外部存储设备中加载环境变量。 6. 初始化硬件 在U-boot启动过程中,需要对各种设备进行初始化。这些设备包括:串口、网络接口、SD卡、USB设备、SPI设备等。初始化完成后,U-boot才能正常使用这些设备。 7. 加载内核 U-boot负责加载内核到指定的内存地址。这个过程可以通过很多方式来完成:串口、SD卡、网络等。在加载内核之前,U-boot还会加载设备树文件(DTB)。 8. 启动内核 U-boot会将内核启动参数(包括设备树的地址)传递给内核,并通过软件跳转实现内核启动。此时,U-boot的使命就完成了,内核将接管系统的控制权。 总之,U-boot启动过程非常复杂,但是也非常重要。因为U-boot提供了系统启动所需的所有基础设施,从而保证了Linux系统的正常运行。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值