日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring源码分析——Bean的生命周期

發布時間:2025/3/19 javascript 12 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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容器加載。

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/org/springframework/context/support/simpleContext.xml");

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加載過程的核心內容,根據上面的介紹,我們可以了解到

  • ClassPathXmlApplicationContext 通過父類的的構造方法創建了上下文
  • 從配置文件的定義中加載了所有的bean,并且默認創建都是singletons
  • 在配置完上下文之后進一步調用refresh方法
  • 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()
    這個方法意思是為刷新準備一個上下文,那進入這個方法,看它提供了什么?

    /*** Prepare this context for refreshing, setting its startup date and* active flag as well as performing any initialization of property sources.*/protected void prepareRefresh() {// 記一個開始時間this.startupDate = System.currentTimeMillis();this.closed.set(false);this.active.set(true);if (logger.isInfoEnabled()) {logger.info("Refreshing " + this);}// 初始化占位符屬性,此處是空方法,以供子類繼承擴展initPropertySources();// 驗證標記為所需的所有屬性都是可解析的// see ConfigurablePropertyResolver#setRequiredPropertiesgetEnvironment().validateRequiredProperties();// 這里是收集前期的應用事件// to be published once the multicaster is available...this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();}

    4.2、ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()
    這個方法主要是告訴子類刷新bean工廠,這個類的代碼如下:

    /*** 子類刷新內部工廠,如果子類覆蓋refreshBeanFactory方法* @return the fresh BeanFactory instance* @see #refreshBeanFactory()* @see #getBeanFactory()*/protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (logger.isDebugEnabled()) {logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);}return beanFactory;}

    這里的refreshBeanFactory是在AbstractRefreshableApplicationContext里實現的,這里附一下DefaultListableBeanFactory的UML圖

    這里就不貼代碼了,這個obtainFreshBeanFactory的目的如下:
    1.如果之前存在beanfactory則銷毀
    2.創建一個DefaultListableBeanFactory類型的beanfactory
    3.加載DefaultListableBeanFactory

    4.3、prepareBeanFactory(beanFactory);
    在上下文中準備bean工廠

    /*** Configure the factory's standard context characteristics,* such as the context's ClassLoader and post-processors.* @param beanFactory the BeanFactory to configure*/protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 設置類加載器:存在則直接設置/不存在則新建一個默認類加載器beanFactory.setBeanClassLoader(getClassLoader());// 設置EL表達式解析器(Bean初始化完成后填充屬性時會用到)beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));//設置屬性注冊解析器PropertyEditorbeanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));//將當前的ApplicationContext對象交給ApplicationContextAwareProcessor類來處理,從而在Aware接口實現類中的注入applicationContextbeanFactory.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);// 注冊可以解析的自動裝配// MessageSource registered (and found for autowiring) as a bean.beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// Register early post-processor for detecting inner beans as ApplicationListeners.beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// 如果當前BeanFactory包含loadTimeWeaver Bean,//說明存在類加載期織入AspectJ,則把當前BeanFactory交給類加載期BeanPostProcessor//實現類LoadTimeWeaverAwareProcessor來處理,從而實現類加載期織入AspectJ的目的。if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// Set a temporary ClassLoader for type matching.beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}//注冊當前容器環境environment組件Bean.if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}//注冊系統配置的systemProperties組件Beanif (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}//注冊系統環境systemEnvironment組件Beanif (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}}

    4.4、 postProcessBeanFactory(beanFactory)
    調用上下文中注冊為bean的工廠處理器。

    /*** 在標準出書畫之后修改應用程序上下文的bean factory* 所有bean定義都將被加載,但是還沒有bean被實例化。* 這允許在特定的ApplicationContext實現中注冊特殊的beanpstprocessors等。*/protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {}

    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處理器。

    /*** 實例化并注冊所有beanPostProcessorbean,如果給定顯式順序,則遵循顯式順序。*/protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);}

    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();
    初始化此上下文的消息源。

    /*** Initialize the MessageSource.* Use parent's if none defined in this context.*/protected void initMessageSource() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);// Make MessageSource aware of parent MessageSource.if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;if (hms.getParentMessageSource() == null) {// Only set parent context as parent MessageSource if no parent MessageSource// registered already.hms.setParentMessageSource(getInternalParentMessageSource());}}if (logger.isDebugEnabled()) {logger.debug("Using MessageSource [" + this.messageSource + "]");}}else {// Use empty MessageSource to be able to accept getMessage calls.DelegatingMessageSource dms = new DelegatingMessageSource();dms.setParentMessageSource(getInternalParentMessageSource());this.messageSource = dms;beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);if (logger.isDebugEnabled()) {logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +"': using default [" + this.messageSource + "]");}}}

    4.8、 initApplicationEventMulticaster();
    為上下文初始化事件廣播

    /*** 初始化應用容器事件,如果沒有定義的話就用默認的SimpleApplicationEventMulticaster **/protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {this.applicationEventMulticaster =beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);if (logger.isDebugEnabled()) {logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");}}else {this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);if (logger.isDebugEnabled()) {logger.debug("Unable to locate ApplicationEventMulticaster with name '" +APPLICATION_EVENT_MULTICASTER_BEAN_NAME +"': using default [" + this.applicationEventMulticaster + "]");}}}

    附一下SimpleApplicationEventMulticaster的UML圖

    4.9、onRefresh()
    初始化特定上下文子類中的其他特殊bean。

    /*** 這個是一個模板方法,為特殊的bean初始化用,在單例實例化之前* */protected void onRefresh() throws BeansException {// For subclasses: do nothing by default.}

    4.10. registerListeners();
    注冊監聽器

    /*** 添加實現了ApplicationListener的監聽器* 不會影響哪些沒有注冊成bean的偵聽器*/protected void registerListeners() {// Register statically specified listeners first.for (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);}// 不要在這里初始化FactoryBeans:我們需要保留所有常規bean// 未初始化以允許后處理器應用于它們!String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);}// 發布早期的應用程序event,這里使用就是觀察者設計模式Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;this.earlyApplicationEvents = null;if (earlyEventsToProcess != null) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);}}}

    4.11、 finishBeanFactoryInitialization(beanFactory)
    實例化所有剩余的(非延遲初始化)單例。

    /*** 完成上下文的初始化,初始化所有剩余的bean*/protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// Initialize conversion service for this context.if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}//如果沒有bean后處理器則注冊一個默認的解析器EmbeddedValueResolverif (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(new StringValueResolver() {@Overridepublic String resolveStringValue(String strVal) {return getEnvironment().resolvePlaceholders(strVal);}});}// 盡早初始化LoadTimeWeaverAware bean,以便盡早注冊其轉換器。String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// 停止使用臨時類加載器進行類型匹配。beanFactory.setTempClassLoader(null);// 允許緩存所有bean定義元數據,不需要進一步更改。beanFactory.freezeConfiguration();// 實例化所有剩余的(非延遲初始化)單例beanFactory.preInstantiateSingletons();}

    4.12、 finishRefresh()
    最后一步:發布對應的事件。這一步bean加載就結束了,通知相應的監聽器。

    /*** 完成容器上下文的刷新,執行onRefresh()方法并發布事件* org.springframework.context.event.ContextRefreshedEvent*/protected void finishRefresh() {// 初始化生命周期處理器initLifecycleProcessor();// 將增殖刷新到生命周期getLifecycleProcessor().onRefresh();// 發布最終的事件.publishEvent(new ContextRefreshedEvent(this));//參與MBean如果存在.LiveBeansView.registerApplicationContext(this);}

    附bean生命周期DefaultLifecycleProcessor的UML

    4.13、 resetCommonCaches();
    在Spring的核心中重置常見的內省緩存,因為我們可能不再需要singleton bean的元數據了

    /*** Reset Spring's common core caches, in particular the {@link ReflectionUtils},* {@link ResolvableType} and {@link CachedIntrospectionResults} caches.* @since 4.2* @see ReflectionUtils#clearCache()* @see ResolvableType#clearCache()* @see CachedIntrospectionResults#clearClassLoader(ClassLoader)*/protected void resetCommonCaches() {ReflectionUtils.clearCache();ResolvableType.clearCache();CachedIntrospectionResults.clearClassLoader(getClassLoader());}

    總結

    以上是生活随笔為你收集整理的Spring源码分析——Bean的生命周期的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。