1. 引言“請(qǐng)你描述下 Spring Bean 的生命周期?”,這是面試官考察 Spring 的常用問(wèn)題,可見(jiàn)是 Spring 中很重要的知識(shí)點(diǎn)。 我之前在準(zhǔn)備面試時(shí),去網(wǎng)上搜過(guò)答案,大多以下圖給出的流程作為答案。 但是當(dāng)我第一次看到該圖時(shí),就產(chǎn)生了很多困擾,“Aware,BeanPostProcessor......這些都是什么??!而且這么多步驟,太多了,該怎么記啊!”。 其實(shí)要記憶該過(guò)程,還是需要我們先去理解,本文將從以下兩方面去幫助理解 Bean 的生命周期:
2. 生命周期的概要流程Bean 的生命周期概括起來(lái)就是?4 個(gè)階段:
下面我們結(jié)合代碼來(lái)直觀的看下,在 doCreateBean() 方法中能看到依次執(zhí)行了這 4 個(gè)階段: //?AbstractAutowireCapableBeanFactory.javaprotected ?Object?doCreateBean(final ?String ?beanName ,? final ?RootBeanDefinition ?mbd ,? final ?@Nullable ? Object [] ?args ) ????throws ?BeanCreationException? {???? //?1.?實(shí)例化 ????BeanWrapper ?instanceWrapper? =? null;???? if ?( instanceWrapper? ==? null) ? { ????????instanceWrapper? = ?createBeanInstance ( beanName , ?mbd , ?args ); ???? } ???? Object ?exposedObject? = ?bean ;???? try ?{???????? //?2.?屬性賦值 ????????populateBean ( beanName , ?mbd , ?instanceWrapper );???????? //?3.?初始化 ????????exposedObject? = ?initializeBean ( beanName , ?exposedObject , ?mbd ); ???? }???? //?4.?銷(xiāo)毀-注冊(cè)回調(diào)接口 ????try ?{ ????????registerDisposableBeanIfNecessary ( beanName , ?bean , ?mbd ); ???? }???? return ?exposedObject ; } 由于初始化包含了第 3~7步,較復(fù)雜,所以我們進(jìn)到 initializeBean() 方法里具體看下其過(guò)程(注釋的序號(hào)對(duì)應(yīng)圖中序號(hào)): //?AbstractAutowireCapableBeanFactory.javaprotected?Object?initializeBean(final?String?beanName,?final?Object?bean,?@Nullable?RootBeanDefinition?mbd)?{????//?3.?檢查?Aware?相關(guān)接口并設(shè)置相關(guān)依賴(lài)????if?(System.getSecurityManager()?!=?null)?{????????AccessController.doPrivileged((PrivilegedAction<Object>)?()?->?{????????????invokeAwareMethods(beanName,?bean);????????????return?null;????????},?getAccessControlContext());????}????else?{????????invokeAwareMethods(beanName,?bean);????}????//?4.?BeanPostProcessor?前置處理????Object?wrappedBean?=?bean;????if?(mbd?==?null?||?!mbd.isSynthetic())?{????????wrappedBean?=?applyBeanPostProcessorsBeforeInitialization(wrappedBean,?beanName);????}????//?5.?若實(shí)現(xiàn)?InitializingBean?接口,調(diào)用?afterPropertiesSet()?方法????//?6.?若配置自定義的?init-method方法,則執(zhí)行????try?{????????invokeInitMethods(beanName,?wrappedBean,?mbd);????}????catch?(Throwable?ex)?{????????throw?new?BeanCreationException(????????????(mbd?!=?null???mbd.getResourceDescription()?:?null),????????????beanName,?"Invocation?of?init?method?failed",?ex);????}????//?7.?BeanPostProceesor?后置處理????if?(mbd?==?null?||?!mbd.isSynthetic())?{????????wrappedBean?=?applyBeanPostProcessorsAfterInitialization(wrappedBean,?beanName);????}????return?wrappedBean;} 在 invokInitMethods() 方法中會(huì)檢查 InitializingBean 接口和 init-method 方法,銷(xiāo)毀的過(guò)程也與其類(lèi)似: //?DisposableBeanAdapter.javapublic?void?destroy()?{????//?9.?若實(shí)現(xiàn)?DisposableBean?接口,則執(zhí)行?destory()方法????if?(this.invokeDisposableBean)?{????????try?{????????????if?(System.getSecurityManager()?!=?null)?{????????????????AccessController.doPrivileged((PrivilegedExceptionAction<Object>)?()?->?{????????????????????((DisposableBean)?this.bean).destroy();????????????????????return?null;????????????????},?this.acc);????????????}????????????else?{????????????????((DisposableBean)?this.bean).destroy();????????????}????????}????}????//?10.?若配置自定義的?detory-method?方法,則執(zhí)行????if?(this.destroyMethod?!=?null)?{????????invokeCustomDestroyMethod(this.destroyMethod);????}????else?if?(this.destroyMethodName?!=?null)?{????????Method?methodToInvoke?=?determineDestroyMethod(this.destroyMethodName);????????if?(methodToInvoke?!=?null)?{????????????invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));????????}????}} 從 Spring 的源碼我們可以直觀的看到其執(zhí)行過(guò)程,而我們記憶其過(guò)程便可以從這 4 個(gè)階段出發(fā),實(shí)例化、屬性賦值、初始化、銷(xiāo)毀。其中細(xì)節(jié)較多的便是初始化,涉及了 Aware、BeanPostProcessor、InitializingBean、init-method 的概念。這些都是 Spring 提供的擴(kuò)展點(diǎn),其具體作用將在下一節(jié)講述。 3. 擴(kuò)展點(diǎn)的作用3.1 Aware 接口若 Spring 檢測(cè)到 bean 實(shí)現(xiàn)了 Aware 接口,則會(huì)為其注入相應(yīng)的依賴(lài)。所以通過(guò)讓bean 實(shí)現(xiàn) Aware 接口,則能在 bean 中獲得相應(yīng)的 Spring 容器資源。 Spring 中提供的 Aware 接口有:
其代碼實(shí)現(xiàn)如下: //?AbstractAutowireCapableBeanFactory.javaprivate?void?invokeAwareMethods(final?String?beanName,?final?Object?bean)?{????if?(bean?instanceof?Aware)?{????????if?(bean?instanceof?BeanNameAware)?{????????????((BeanNameAware)?bean).setBeanName(beanName);????????}????????if?(bean?instanceof?BeanClassLoaderAware)?{????????????((BeanClassLoaderAware)?bean).setBeanClassLoader(bcl);????????}????????if?(bean?instanceof?BeanFactoryAware)?{????????????((BeanFactoryAware)?bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);????????}????}} 以上是針對(duì) BeanFactory 類(lèi)型的容器,而對(duì)于 ApplicationContext 類(lèi)型的容器,也提供了 Aware 接口,只不過(guò)這些 Aware 接口的注入實(shí)現(xiàn),是通過(guò) BeanPostProcessor 的方式注入的,但其作用仍是注入依賴(lài)。
其代碼實(shí)現(xiàn)如下: //?ApplicationContextAwareProcessor.javaprivate?void?invokeAwareInterfaces(Object?bean)?{????if?(bean?instanceof?EnvironmentAware)?{????????((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());????}????if?(bean?instanceof?EmbeddedValueResolverAware)?{????????((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);????}????if?(bean?instanceof?ResourceLoaderAware)?{????????((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);????}????if?(bean?instanceof?ApplicationEventPublisherAware)?{????????((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);????}????if?(bean?instanceof?MessageSourceAware)?{????????((MessageSourceAware)bean).setMessageSource(this.applicationContext);????}????if?(bean?instanceof?ApplicationContextAware)?{????????((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);????}} 3.2 BeanPostProcessorBeanPostProcessor 是 Spring 為*修改 bean *提供的強(qiáng)大擴(kuò)展點(diǎn),其可作用于容器中所有 bean,其定義如下: public?interface?BeanPostProcessor?{????//?初始化前置處理????default?Object?postProcessBeforeInitialization(Object?bean,?String?beanName)?throws?BeansException?{????????return?bean;????}????//?初始化后置處理????default?Object?postProcessAfterInitialization(Object?bean,?String?beanName)?throws?BeansException?{????????return?bean;????}} 常用場(chǎng)景有:
//?AbstractAutoProxyCreator.javapublic?Object?postProcessBeforeInstantiation(Class<?>?beanClass,?String?beanName)?{????TargetSource?targetSource?=?getCustomTargetSource(beanClass,?beanName);????if?(targetSource?!=?null)?{????????if?(StringUtils.hasLength(beanName))?{????????????this.targetSourcedBeans.add(beanName);????????}????????Object[]?specificInterceptors?=?getAdvicesAndAdvisorsForBean(beanClass,?beanName,?targetSource);????????Object?proxy?=?createProxy(beanClass,?beanName,?specificInterceptors,?targetSource);????????this.proxyTypes.put(cacheKey,?proxy.getClass());????????//?返回代理類(lèi)????????return?proxy;????}????return?null;} 3.3 InitializingBean 和 init-methodInitializingBean 和 init-method 是 Spring 為?bean 初始化提供的擴(kuò)展點(diǎn)。 InitializingBean接口 的定義如下: public?interface?InitializingBean?{????void?afterPropertiesSet()?throws?Exception;} 在 afterPropertiesSet() 方法寫(xiě)初始化邏輯。 指定 init-method 方法,指定初始化方法: <?xml?version="1.0"?encoding="UTF-8"?><beans?xmlns="http://www./schema/beans"???????xmlns:xsi="http://www./2001/XMLSchema-instance"???????xsi:schemaLocation="http://www./schema/beans?http://www./schema/beans/spring-beans.xsd">????<bean?id="demo"?class="com.chaycao.Demo"?init-method="init()"/></beans> DisposableBean 和 destory-method 與上述類(lèi)似,就不描述了。 4. 總結(jié)最后總結(jié)下如何記憶 Spring Bean 的生命周期:
|
|
來(lái)自: 印度阿三17 > 《開(kāi)發(fā)》