spring boot 2.0 源码分析(五)

  • 时间:
  • 浏览:0
  • 来源:大发时时彩官网_大发时时彩邀请码_大发时时彩娱乐平台

在上一篇文章中我们我们我们 我们我们我们 儿儿删剪分析了spring boot是怎么才能 才能 准备上下文环境的,今天我们我们我们 我们我们我们 儿儿来看一下run函数剩余的内容。还是先把run函数贴出来:

    /**
     * Run the Spring application, creating and refreshing a new
     * {@link ApplicationContext}.
     * @param args the application arguments (usually passed from a Java main method)
     * @return a running {@link ApplicationContext}
     */
    public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        configureHeadlessProperty();
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                    args);
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                    applicationArguments);
            configureIgnoreBeanInfo(environment);
            Banner printedBanner = printBanner(environment);
            context = createApplicationContext();
            exceptionReporters = getSpringFactoriesInstances(
                    SpringBootExceptionReporter.class,
                    new Class[] { ConfigurableApplicationContext.class }, context);
            prepareContext(context, environment, listeners, applicationArguments,
                    printedBanner);
            refreshContext(context);
            afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass)
                        .logStarted(getApplicationLog(), stopWatch);
            }
            listeners.started(context);
            callRunners(context, applicationArguments);
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, listeners);
            throw new IllegalStateException(ex);
        }

        try {
            listeners.running(context);
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, null);
            throw new IllegalStateException(ex);
        }
        return context;
    }

我们我们我们 我们我们我们 儿儿接着往下看,来看一下this.refreshContext(context);函数,你什儿 函数用于刷新上下文,跟踪到源码看一下:

    private void refreshContext(ConfigurableApplicationContext context) {
        refresh(context);
        if (this.registerShutdownHook) {
            try {
                context.registerShutdownHook();
            }
            catch (AccessControlException ex) {
                // Not allowed in some environments.
            }
        }
    }

在refreshContext函数中,第一行调用了refresh(context);跳转了一下,下面的代码是注册了一个多多多多多多 应用关闭的函数钩子。

先来看refresh(context);函数:

    /**
     * Refresh the underlying {@link ApplicationContext}.
     * @param applicationContext the application context to refresh
     */
    protected void refresh(ApplicationContext applicationContext) {
        Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
        ((AbstractApplicationContext) applicationContext).refresh();
    }

通过代码跟踪分析发现,实在是调用了AbstractApplicationContext中的refresh依据。

在ServletWebServerApplicationContext和ReactiveWebServerApplicationContext的refresh函数中删剪都是调用了super.refresh();

    public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        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();
            }

        }
    }

在这段代码中我们我们我们 我们我们我们 儿儿才能看完,其是使用了上下文中的startupShutdownMonitor属性创建一个多多多多多多 同步代码库来执行的刷新动作。首先是实验this.prepareRefresh();准备刷新上下文:

    protected void prepareRefresh() {
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);
        if(this.logger.isInfoEnabled()) {
            this.logger.info("Refreshing " + this);
        }

        this.initPropertySources();
        this.getEnvironment().validateRequiredProperties();
        this.earlyApplicationEvents = new LinkedHashSet();
    }

接着获取了bean工厂之后,设置了有些bean工厂的环境:

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.setBeanClassLoader(this.getClassLoader());
        beanFactory.setBeanExpressionResolver(
        new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(
        new ResourceEditorRegistrar(this, this.getEnvironment()));
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
        if(beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(
            new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        if(!beanFactory.containsLocalBean("environment")) {
            beanFactory.registerSingleton("environment", this.getEnvironment());
        }

        if(!beanFactory.containsLocalBean("systemProperties")) {
            beanFactory.registerSingleton("systemProperties", 
            this.getEnvironment().getSystemProperties());
        }

        if(!beanFactory.containsLocalBean("systemEnvironment")) {
            beanFactory.registerSingleton("systemEnvironment", 
            this.getEnvironment().getSystemEnvironment());
        }

    }

接下来是发送了一个多多多多多多 bean工厂的处里信号,其中ServletWebServerApplicationContext中的实现是在bean工厂里换成了一个多多多多多多 WebApplicationContextServletContextAwareProcessor处里器:

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.addBeanPostProcessor(
        new WebApplicationContextServletContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    }

紧接着可是调用了这处里器,有些注册到bean工厂。有些可是分别调用了initMessageSource()和initApplicationEventMulticaster()用于初始化监听器和监听管理器:

    protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if(beanFactory.containsLocalBean("messageSource")) {
            this.messageSource = (MessageSource)beanFactory
            .getBean("messageSource", MessageSource.class);
            if(this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
                HierarchicalMessageSource dms = (HierarchicalMessageSource)this.messageSource;
                if(dms.getParentMessageSource() == null) {
                    dms.setParentMessageSource(this.getInternalParentMessageSource());
                }
            }

            if(this.logger.isDebugEnabled()) {
                this.logger.debug("Using MessageSource [" + this.messageSource + "]");
            }
        } else {
            DelegatingMessageSource dms1 = new DelegatingMessageSource();
            dms1.setParentMessageSource(this.getInternalParentMessageSource());
            this.messageSource = dms1;
            beanFactory.registerSingleton("messageSource", this.messageSource);
            if(this.logger.isDebugEnabled()) {
                this.logger.debug("Unable to locate MessageSource with name 
                \'messageSource\': using default [" + this.messageSource + "]");
            }
        }

    }

    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if(beanFactory.containsLocalBean("applicationEventMulticaster")) {
            this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory
            .getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
            if(this.logger.isDebugEnabled()) {
                this.logger.debug("Using ApplicationEventMulticaster [" + 
                this.applicationEventMulticaster + "]");
            }
        } else {
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton("applicationEventMulticaster", 
            this.applicationEventMulticaster);
            if(this.logger.isDebugEnabled()) {
                this.logger.debug("Unable to locate ApplicationEventMulticaster with name 
                \'applicationEventMulticaster\':
                 using default [" + this.applicationEventMulticaster + "]");
            }
        }

    }

在initMessageSource函数中会首先判断beanFactory工厂中不是可能性占据 messageSource,可能性不占据 就会为当前的messageSource创建一个多多多多多多 新的DelegatingMessageSource。

initApplicationEventMulticaster的初始化依据跟initMessageSource差太多,这里不再多述。继续看run函数,接下来调用onRefresh()函数,你什儿 函数可是发送一个多多多多多多 刷新的事件,源码中并没得 具体的实现。接着放下看,this.registerListeners();把spring容器内的listener和beanfactory的listener都换成到广播器中:

    protected void registerListeners() {
        Iterator listenerBeanNames = this.getApplicationListeners().iterator();

        while(listenerBeanNames.hasNext()) {
            ApplicationListener earlyEventsToProcess = (ApplicationListener)listenerBeanNames.next();
            this.getApplicationEventMulticaster().addApplicationListener(earlyEventsToProcess);
        }

        String[] var6 = this.getBeanNamesForType(ApplicationListener.class, true, false);
        String[] var7 = var6;
        int var3 = var6.length;

        for(int earlyEvent = 0; earlyEvent < var3; ++earlyEvent) {
            String listenerBeanName = var7[earlyEvent];
            this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        Set var8 = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if(var8 != null) {
            Iterator var9 = var8.iterator();

            while(var9.hasNext()) {
                ApplicationEvent var10 = (ApplicationEvent)var9.next();
                this.getApplicationEventMulticaster().multicastEvent(var10);
            }
        }

    }

通过this.finishBeanFactoryInitialization(beanFactory);实例化BeanFactory 中可能性被注册有些没被实例化的所有实例。初始化的过程中各种BeanPostProcessor就结束了生效了:

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        if(beanFactory.containsBean("conversionService") && 
        beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
        
            beanFactory.setConversionService((ConversionService)beanFactory
            .getBean("conversionService", ConversionService.class));
        }

        if(!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver((strVal) -> {
                return this.getEnvironment().resolvePlaceholders(strVal);
            });
        }

        String[] weaverAwareNames = beanFactory
        .getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        String[] var3 = weaverAwareNames;
        int var4 = weaverAwareNames.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String weaverAwareName = var3[var5];
            this.getBean(weaverAwareName);
        }

        beanFactory.setTempClassLoader((ClassLoader)null);
        beanFactory.freezeConfiguration();
        beanFactory.preInstantiateSingletons();
    }

接下来调用finishRefresh()函数用于完成刷新后的有些扫尾工作,包括产生的缓存、初始化生命周期处里器LifecycleProcessor,并调用其onRefresh()依据、发布事件、调用LiveBeansView的registerApplicationContext注册context。

    protected void finishRefresh() {
        this.clearResourceCaches();
        this.initLifecycleProcessor();
        this.getLifecycleProcessor().onRefresh();
        this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
        LiveBeansView.registerApplicationContext(this);
    }

接着看run函数,在刷新完context后,调用了一个多多多多多多 afterRefresh函数,你什儿 函数前面可能性说过了,是为了给ApplicationContext的子类留下的一个多多多多多多 扩展点。

有些调用了listeners.started(context);,把监听器设置成了可能性启动的请况。最后调用了callRunners函数,获取所有的ApplicationRunner和CommandLineRunner有些调用我们我们我们 我们我们我们 儿的run依据:

    private void callRunners(ApplicationContext context, ApplicationArguments args) {
        List<Object> runners = new ArrayList<>();
        runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
        runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
        AnnotationAwareOrderComparator.sort(runners);
        for (Object runner : new LinkedHashSet<>(runners)) {
            if (runner instanceof ApplicationRunner) {
                callRunner((ApplicationRunner) runner, args);
            }
            if (runner instanceof CommandLineRunner) {
                callRunner((CommandLineRunner) runner, args);
            }
        }
    }

总结:spring boot 2.0在启动的之后,首先会调用SpringApplication的构造函数进行初始化,调用实例函数run,在run函数中,首先获取监听器,并设置成启动请况,顶端准备环境prepareEnvironment,准备prepareContext上下文,刷新上下文refreshContext,最后调用callRunners来依次调用注册的Runner。

猜你喜欢

乐视414电商节再爆壕礼:414当天或将414元秒豪车

2017-04-1413:43:03  牛华网    我就要评论()字号:T|T4月5号,乐视414生态电商节再次为乐迷们送上一轮新的福利,推出半价秒汽车的活动。据悉,414当

2019-12-15

5G系统频率使用许可将于年内发放

IT之家10月29日消息据媒体报道,工信部近日表示,5G系统频率使用许可将在年内发放,一起去工信部还制定了物联网、车联网频率使用的规划。据了解,工信部之也不迟迟未签署5G频率和

2019-12-15

专家:探索现代科技方式传播传承昆曲艺术

“面对多元文化竞争中传统戏曲受到挤压、与大众出显鸿沟,应该架起科技传播的桥梁。”中国戏曲协会原会长薛若琳23日表示,相比去传统剧院观看,还时要探索利用短视频、融媒体等新法律土办

2019-12-15

如何在discuz x2.0里自创建分类信息(以招聘为例)

Discuz功能之强大,亲戚亲戚给你们有目共睹,你想的没法多没法多东西它都还前要实现,比如招聘信息,下面就向亲戚亲戚给你们讲解下咋样在discuz里创建自定义的分类信息,实例地

2019-12-15

图书管理系统源码(三层架构)|图书管理系统源码(三层架构) v1.0下载

一、源码描述这是一款学生原创的图书管理系统源码,采用了三层架构的技术,基本上实现了图书管理系统的功能,都还可以 作为新手练习将会课程设计使用,感兴趣的他们 赶紧下载哦。二

2019-12-15