javascript
Spring源码分析——Bean的生命周期
文章目錄
- 說明
- 測試代碼
說明
本文從源碼的角度分析Spring中Bean的加載過程,本文使用的Spring版本為4.3.25.RELEASE
測試代碼
測試代碼如下,根據這段簡單的測試代碼,一步步跟蹤Spring中Bean的生命周期。
@Testpublic void testSingleConfigLocation() {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/org/springframework/context/support/simpleContext.xml");Assert.assertTrue(ctx.containsBean("someMessageSource"));ctx.close();}一行行的分析上面這段代碼
1、首先看ClassPathXmlApplicationContext容器加載。
2、參考ClassPathXmlApplicationContext的UML圖。 附上ClassPathXmlApplicationContext的UML圖,以便于理解接口之間的關系。
3、跟蹤代碼到下面這個構造方法的實現
/*** Create a new ClassPathXmlApplicationContext, loading the definitions* from the given XML file and automatically refreshing the context.* @param configLocation resource location* @throws BeansException if context creation failed*/public ClassPathXmlApplicationContext(String configLocation) throws BeansException {this(new String[] {configLocation}, true, null);}/*** Create a new ClassPathXmlApplicationContext with the given parent,* loading the definitions from the given XML files.* @param configLocations array of resource locations* @param refresh whether to automatically refresh the context,* loading all bean definitions and creating all singletons.* Alternatively, call refresh manually after further configuring the context.* @param parent the parent context* @throws BeansException if context creation failed* @see #refresh()*/public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)throws BeansException {super(parent);setConfigLocations(configLocations);if (refresh) {refresh();}}這個構造方法就是整個Bean加載過程的核心內容,根據上面的介紹,我們可以了解到
4、最主要的就是這個refresh方法了,下面分析一下這個refresh方法
@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 1、Prepare this context for refreshing.prepareRefresh();// 2、Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 3、Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);try {// 4、Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// 5、Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);// 6、Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);// 7、Initialize message source for this context.initMessageSource();// 8、Initialize event multicaster for this context.initApplicationEventMulticaster();// 9、Initialize other special beans in specific context subclasses.onRefresh();// 10、Check for listener beans and register them.registerListeners();// 11、Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);// 12、Last step: publish corresponding event.finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {//13、 Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}}}這個fresh方法中包含了13個步,那就把這13一步一步的分析。
4.1、prepareRefresh()
這個方法意思是為刷新準備一個上下文,那進入這個方法,看它提供了什么?
4.2、ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()
這個方法主要是告訴子類刷新bean工廠,這個類的代碼如下:
這里的refreshBeanFactory是在AbstractRefreshableApplicationContext里實現的,這里附一下DefaultListableBeanFactory的UML圖
這里就不貼代碼了,這個obtainFreshBeanFactory的目的如下:
1.如果之前存在beanfactory則銷毀
2.創建一個DefaultListableBeanFactory類型的beanfactory
3.加載DefaultListableBeanFactory
4.3、prepareBeanFactory(beanFactory);
在上下文中準備bean工廠
4.4、 postProcessBeanFactory(beanFactory)
調用上下文中注冊為bean的工廠處理器。
4.5、invokeBeanFactoryPostProcessors(beanFactory)
/*** 如果有順序就按照順序實例化所有注冊的BeanFactoryPostProcessor* */protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// 如果當前BeanFactory包含loadTimeWeaver Bean,//說明存在類加載期織入AspectJ,則把當前BeanFactory交給類加載期BeanPostProcessor//實現類LoadTimeWeaverAwareProcessor來處理,從而實現類加載期織入AspectJ的目的。if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}4.6、 registerBeanPostProcessors(beanFactory)
注冊攔截bean創建的bean處理器。
PostProcessorRegistrationDelegate.registerBeanPostProcessors的實現如下
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);// 注冊BeanPostProcessorChecker,在BeanPostProcessor實例化期間創建bean時記錄信息消息int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));//區分BeanPostProcessors是實現了PriorityOrdered、Ordered、其他List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();List<String> orderedPostProcessorNames = new ArrayList<String>();List<String> nonOrderedPostProcessorNames = new ArrayList<String>();for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// First, register the BeanPostProcessors that implement PriorityOrdered.sortPostProcessors(priorityOrderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// Next, register the BeanPostProcessors that implement Ordered.List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();for (String ppName : orderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);orderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}sortPostProcessors(orderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, orderedPostProcessors);// Now, register all regular BeanPostProcessors.List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);// Finally, re-register all internal BeanPostProcessors.sortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);//重新注冊后處理器,以便將內部bean檢測為應用程序偵聽器,并將其移動到處理器鏈的末端(用于獲取代理等)beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}4.7、initMessageSource();
初始化此上下文的消息源。
4.8、 initApplicationEventMulticaster();
為上下文初始化事件廣播
附一下SimpleApplicationEventMulticaster的UML圖
4.9、onRefresh()
初始化特定上下文子類中的其他特殊bean。
4.10. registerListeners();
注冊監聽器
4.11、 finishBeanFactoryInitialization(beanFactory)
實例化所有剩余的(非延遲初始化)單例。
4.12、 finishRefresh()
最后一步:發布對應的事件。這一步bean加載就結束了,通知相應的監聽器。
附bean生命周期DefaultLifecycleProcessor的UML
4.13、 resetCommonCaches();
在Spring的核心中重置常見的內省緩存,因為我們可能不再需要singleton bean的元數據了
總結
以上是生活随笔為你收集整理的Spring源码分析——Bean的生命周期的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringMVC学习(四)——Spri
- 下一篇: Spring小知识——profile配置