Spring ApplicationContext(十)finishRefresh

ApplicationContext(十)finishRefresh

Spring 系列目錄(http://www.javashuo.com/article/p-kqecupyl-bm.html)html

通過以上 11 步,ApplicationContext 的刷新工做基本完成,就剩下最後一點收尾的工做。java

在 Spring 中還提供了 Lifecycle 接口, Lifecycle 中包含 start/stop 方法,實現此接口後 Spring 會保證在啓動的時候調用其 start 方法開始生命週期,並在 Spring 關閉的時候調用 stop 方法來結束生命週期,一般用來配置後臺程序,在啓動後一直運行(如對 MQ 進行輪詢等)而 ApplicationContext 的初始化最後正是保證了這一功能的實現。app

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);
}

1、initLifecycleProcessor

當 ApplicationContext 啓動或中止時,它會經過 initLifecycleProcessor 來與全部聲明的 bean 的週期作狀態更新,而在 LifecycleProcessor 的使用前首先須要初始化。this

protected void initLifecycleProcessor() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
        this.lifecycleProcessor =
                beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
    }
    else {
        DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
        defaultProcessor.setBeanFactory(beanFactory);
        this.lifecycleProcessor = defaultProcessor;
        beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
    }
}

2、onRefresh

啓動全部實現了 Lifecycle 接口的 beancode

public void onRefresh() {
    startBeans(true);
    this.running = true;
}

// Spring 內部用
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();
        }
    }
}

3. publishEvent

當完成 ApplicationContext 初始化的時候,要經過 Spring 中的事件發佈機制來發出 ContextRefreshedEvent 事件,以保證對應的監聽器能夠作進一步的邏輯處理。htm

protected void publishEvent(Object event, ResolvableType eventType) {
    Assert.notNull(event, "Event must not be null");

    // 1. 若是 event 不是 ApplicationEvent,則須要進行封裝成 PayloadApplicationEvent
    ApplicationEvent applicationEvent;
    if (event instanceof ApplicationEvent) {
        applicationEvent = (ApplicationEvent) event;
    }
    else {
        applicationEvent = new PayloadApplicationEvent<Object>(this, event);
        if (eventType == null) {
            eventType = ResolvableType.forClassWithGenerics(PayloadApplicationEvent.class, event.getClass());
        }
    }

    // 2. 發佈事件 event,若是多播器懶加載,尚未初始化則將該事件先放到 earlyApplicationEvents 容器中
    //    等待多播器建立好了再發布事件 ???
    if (this.earlyApplicationEvents != null) {
        this.earlyApplicationEvents.add(applicationEvent);
    }
    else {
        getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
    }

    // 3. 父容器中也須要發佈該事件 event
    if (this.parent != null) {
        if (this.parent instanceof AbstractApplicationContext) {
            ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
        }
        else {
            this.parent.publishEvent(event);
        }
    }
}

天天用心記錄一點點。內容也許不重要,但習慣很重要!blog

相關文章
相關標籤/搜索