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); }
當 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); } }
啓動全部實現了 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(); } } }
當完成 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