Spring源码之ApplicationContext(十)过程刷新

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
免费领取 2000+ 道 Java 面试题

ApplicationContext的初始化的最后一步就是要刷新过程,什么是刷新过程?其实Spring关闭的时候调用stop方法来结束生命周期,通常用来配置后台程序,在启动后一直运行(如对MQ进行轮询等)。我们先来看调用的时序图。(相关资源可到这里下载:http://pan.baidu.com/s/1sjSo9a9

20191123100230\_1.png

首先,Spring先调用的是finishRefresh()的方法。

    /**
         * Finish the refresh of this context, invoking the LifecycleProcessor's
         * onRefresh() method and publishing the
         * {@link org.springframework.context.event.ContextRefreshedEvent}.
         */
        protected void finishRefresh() {
            // Initialize lifecycle processor for this context.
            initLifecycleProcessor();

            // Propagate refresh to lifecycle processor first.
            getLifecycleProcessor().onRefresh();

            // Publish the final event.
            publishEvent(new ContextRefreshedEvent(this));

            // Participate in LiveBeansView MBean, if active.
            LiveBeansView.registerApplicationContext(this);
        }

之后,我们会发现,Spring的ApplicationContext启动或停止时,它会通过LifecycleProcessor来与所有声明的bean的周期做状态,而LifecycleProcessor的使用前首先需要初始化。

    /**
         * Initialize the LifecycleProcessor.
         * Uses DefaultLifecycleProcessor if none defined in the context.
         * @see org.springframework.context.support.DefaultLifecycleProcessor
         */
        protected void initLifecycleProcessor() {
            ConfigurableListableBeanFactory beanFactory = getBeanFactory();
            if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
                this.lifecycleProcessor =
                        beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
                if (logger.isDebugEnabled()) {
                    logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
                }
            }
            else {
                DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
                defaultProcessor.setBeanFactory(beanFactory);
                this.lifecycleProcessor = defaultProcessor;
                beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
                if (logger.isDebugEnabled()) {
                    logger.debug("Unable to locate LifecycleProcessor with name '" +
                            LIFECYCLE_PROCESSOR_BEAN_NAME +
                            "': using default [" + this.lifecycleProcessor + "]");
                }
            }
        }

当做finishRefresh()方法,还有两个的方法调用也是值得我们去跟踪的,那就是onRefresh()的方法,及它间接调用了startBeans的方法。

    @Override
        public void onRefresh() {
            startBeans(true);
            this.running = true;
        }
    private void startBeans(boolean autoStartupOnly) {
            Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
            Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
            for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {
                Lifecycle bean = entry.getValue();
                if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
                    int phase = getPhase(bean);
                    LifecycleGroup group = phases.get(phase);
                    if (group == null) {
                        group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                        phases.put(phase, group);
                    }
                    group.add(entry.getKey(), bean);
                }
            }
            if (phases.size() > 0) {
                List<Integer> keys = new ArrayList<Integer>(phases.keySet());
                Collections.sort(keys);
                for (Integer key : keys) {
                    phases.get(key).start();
                }
            }
        }

最后,我们来看一下publishEvent的源码。

    /**
         * Publish the given event to all listeners.
         * @param event the event to publish (may be an {@link ApplicationEvent}
         * or a payload object to be turned into a {@link PayloadApplicationEvent})
         * @param eventType the resolved event type, if known
         * @since 4.2
         */
        protected void publishEvent(Object event, ResolvableType eventType) {
            Assert.notNull(event, "Event must not be null");
            if (logger.isTraceEnabled()) {
                logger.trace("Publishing event in " + getDisplayName() + ": " + event);
            }

            // Decorate event as an ApplicationEvent if necessary
            ApplicationEvent applicationEvent;
            if (event instanceof ApplicationEvent) {
                applicationEvent = (ApplicationEvent) event;
            }
            else {
                applicationEvent = new PayloadApplicationEvent<Object>(this, event);
                if (eventType == null) {
                    eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
                }
            }

            // Multicast right now if possible - or lazily once the multicaster is initialized
            if (this.earlyApplicationEvents != null) {
                this.earlyApplicationEvents.add(applicationEvent);
            }
            else {
                getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
            }

            // Publish event via parent context as well...
            if (this.parent != null) {
                if (this.parent instanceof AbstractApplicationContext) {
                    ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
                }
                else {
                    this.parent.publishEvent(event);
                }
            }
        }

来源:http://ddrv.cn/a/88268

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » Spring源码之ApplicationContext(十)过程刷新

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏