BeanPostProcessor和BeanFactoryPostProcessor是Spring中兩個(gè)最重要的擴(kuò)展的。如果說BeanFactoryPostProcessor是面向IoC進(jìn)行擴(kuò)展,BeanPostProcessor就是面向Bean進(jìn)行擴(kuò)展。
從上面類結(jié)構(gòu)圖可以看出,BeanPostProcessor是一個(gè)頂層接口,下面有衍生出幾個(gè)接口,實(shí)現(xiàn)對(duì)Bean創(chuàng)建、初始化等各個(gè)階段進(jìn)行更細(xì)化的擴(kuò)展,所以BeanPostProcessor要比BeanFactoryPostProcessor復(fù)雜一些,可以實(shí)現(xiàn)更多擴(kuò)展場(chǎng)景。
(相關(guān)資料圖)
BeanPostProcessor被注冊(cè)到IoC中才能起作用,在refresh()方法中registerBeanPostProcessors(beanFactory);這一語(yǔ)句完成BeanPostProcessor的注冊(cè)工作,注冊(cè)使用:addBeanPostProcessor(BeanPostProcessor beanPostProcessor)方法完成。
注冊(cè)BeanPostProcessor也涉及到先后順序關(guān)系,大致邏輯總結(jié)如下:
1、獲取實(shí)現(xiàn)PriorityOrdered接口的BeanPostProcessor,然后通過getBean()方法實(shí)例化,排序后注冊(cè)到容器中;2、獲取實(shí)現(xiàn)Ordered接口的BeanPostProcessor,然后通過getBean()方法實(shí)例化,排序后注冊(cè)到容器中;3、獲取常規(guī)沒有實(shí)現(xiàn)PriorityOrdered和Ordered接口BeanPostProcessor,然后通過getBean()方法實(shí)例化,注冊(cè)到容器中;4、上述步驟中MergedBeanDefinitionPostProcessor類型會(huì)單獨(dú)存儲(chǔ)到internalPostProcessors集合中,排序后保證放到末尾5、最后移除ApplicationListenerDetector重新追加到最末尾上面只是BeanPostProcessor注冊(cè)先后順序關(guān)系,并不會(huì)涉及到BeanPostProcessor的執(zhí)行,由于BeanPostProcessor擴(kuò)展出幾個(gè)子類,下面我們來分析下每個(gè)子類的執(zhí)行時(shí)機(jī)。
接口定義見下:
public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }}之前分析IoC容器啟動(dòng)流程時(shí),介紹過initializeBean()方法完成Bean的init-method初始化工作,BeanPostProcessor就是在init-method執(zhí)行前后進(jìn)行擴(kuò)展。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //觸發(fā)BeanPostProcessor#postProcessBeforeInitialization()方法執(zhí)行 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } //執(zhí)行init-method方法 invokeInitMethods(beanName, wrappedBean, mbd); if (mbd == null || !mbd.isSynthetic()) { //觸發(fā)BeanPostProcessor#postProcessAfterInitialization()方法執(zhí)行 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean;}再來看下這兩個(gè)方法的調(diào)用邏輯:
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result;}如果有postProcessBeforeInitialization()方法返回null,則表示該擴(kuò)展點(diǎn)提前結(jié)束,不再需要繼續(xù)執(zhí)行后續(xù)BeanPostProcessor的postProcessBeforeInitialization方法。
再來看下postProcessAfterInitialization()方法執(zhí)行邏輯是一樣的:
@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }invokeInitMethods(beanName, wrappedBean, mbd);方法執(zhí)行Bean的init-method方法進(jìn)行初始化,進(jìn)入這個(gè)方法可以發(fā)現(xiàn),這里只會(huì)執(zhí)行實(shí)現(xiàn)InitializingBean和@Bean(initMethod="xxx")這兩種方式設(shè)置的init-method方法,我們平時(shí)使用很多的@PostConstruct注解方式,其實(shí)是通過InitDestroyAnnotationBeanPostProcessor這個(gè)擴(kuò)展類實(shí)現(xiàn):
InitDestroyAnnotationBeanPostProcessor類實(shí)現(xiàn)了DestructionAwareBeanPostProcessor和MergedBeanDefinitionPostProcessor這兩個(gè)接口,間接方式繼承BeanPostProcessor。InitDestroyAnnotationBeanPostProcessor就是在postProcessBeforeInitialization()方法中完成了對(duì)@PostConstruct注解方法的調(diào)用,所以其執(zhí)行優(yōu)先級(jí)比InitializingBean和@Bean(initMethod="xxx")這兩種方式更加靠前。
如果你需要在init-method等Bean的初始化執(zhí)行前后進(jìn)行擴(kuò)展,可以使用此接口實(shí)現(xiàn)。比如:判斷Bean是否是線程池類,如果是則統(tǒng)一設(shè)置管理的線程名前綴:
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof ThreadPoolTaskExecutor) { ((ThreadPoolTaskExecutor) bean).setThreadNamePrefix("Post-"); } return bean;}還比如ApplicationListenerDetector在postProcessAfterInitialization()方法中實(shí)現(xiàn)將ApplicationListener類型的單例Bean注冊(cè)到事件多播器上,實(shí)現(xiàn)對(duì)事件的監(jiān)聽:
public Object postProcessAfterInitialization(Object bean, String beanName) { if (bean instanceof ApplicationListener) { Boolean flag = this.singletonNames.get(beanName); if (Boolean.TRUE.equals(flag)) { // 如果當(dāng)前 ApplicationListener bean scope 是 singleton 單例模式,則將它注冊(cè)到應(yīng)用的事件多播器上 this.applicationContext.addApplicationListener((ApplicationListener>) bean); } else if (Boolean.FALSE.equals(flag)) { // 如果ApplicationListener bean scope 不是 singleton 單例模式,則嘗試輸出警告日志,說明情況,并移除 //所以ApplicationListener類型的只能是單例模式才會(huì)起作用 this.singletonNames.remove(beanName); } } return bean;}還比如ApplicationContextAwareProcessor這個(gè)就是在postProcessBeforeInitialization()方法中實(shí)現(xiàn)如ApplicationContextAware、EnvironmentAware等*Aware接口注入功能。實(shí)現(xiàn)原理非常簡(jiǎn)單,就是判斷Bean是否實(shí)現(xiàn)接口,然后通過setter方式注入即可:
private 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); }}前面分析BeanPostProcessor接口是在Bean的init-method方法執(zhí)行前后進(jìn)行擴(kuò)展,其子接口InstantiationAwareBeanPostProcessor則可以在Bean的創(chuàng)建前后進(jìn)行擴(kuò)展,所以此擴(kuò)展比BeanPostProcessor擴(kuò)展更靠前。
接口定義見下:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { //Bean創(chuàng)建之前回調(diào)該方法,beanClass就是將要被創(chuàng)建的Bean對(duì)應(yīng)的Class信息 @Nullable default Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException { return null; } //Bean創(chuàng)建之后回調(diào)該方法,參數(shù)bean就是創(chuàng)建完成的Bean對(duì)象 default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; } //postProcessProperties()方法在postProcessAfterInstantiation()方法之后緊挨著執(zhí)行,其提供PropertyValues類型入?yún)?,所以在該方法中可以?shí)現(xiàn)依賴操作 @Nullable default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { return null; } //這個(gè)方法標(biāo)注@Deprecated已經(jīng)被廢棄了,被postProcessProperties()方法取代了 @Deprecated @Nullable default PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; }}createBean()方法中Object bean = resolveBeforeInstantiation(beanName, mbdToUse);這條語(yǔ)句中會(huì)觸發(fā)對(duì)postProcessBeforeInstantiation()方法的執(zhí)行。
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { Object bean = resolveBeforeInstantiation(beanName, mbdToUse);//觸發(fā)對(duì)postProcessBeforeInstantiation()方法的執(zhí)行 if (bean != null) { return bean; } ... Object beanInstance = doCreateBean(beanName, mbdToUse, args);//創(chuàng)建Bean實(shí)例(一般真正創(chuàng)建Bean的方法) ...}InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()方法有個(gè)重要特性:如果該方法返回非null結(jié)果,則表示Bean提前創(chuàng)建完成,同時(shí)也會(huì)忽略掉后續(xù)的依賴注入、init-method初始化等步驟執(zhí)行,最后只需要執(zhí)行下BeanPostProcessor#postProcessAfterInitialization這個(gè)方法則整個(gè)Bean的創(chuàng)建流程就全部完成。
總結(jié):在創(chuàng)建對(duì)象之前調(diào)用了postProcessBeforeInstantiation方法可以實(shí)現(xiàn)給擴(kuò)展點(diǎn)一次創(chuàng)建代理的機(jī)會(huì),如果代理對(duì)象返回不為空則不再繼續(xù)常規(guī)方式創(chuàng)建Bean。
我們?cè)賮砜聪?code>InstantiationAwareBeanPostProcessor接口中定義的另兩個(gè)方法執(zhí)行時(shí)機(jī),Bean創(chuàng)建完成后會(huì)執(zhí)行populateBean()進(jìn)行依賴注入,它們就是在這個(gè)方法中進(jìn)行觸發(fā)回調(diào),pupulateBean()方法大致見下:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { //執(zhí)行InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation方法回調(diào) if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } } // 注解注入:后置處理器ibp#postProcessProperties,大名鼎鼎的@Autowired就是在這處理的。 PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { //執(zhí)行InstantiationAwareBeanPostProcessor#postProcessProperties方法回調(diào) for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { //獲取出對(duì)象的所有set get方法,現(xiàn)在是有一個(gè) getClass()方法,因?yàn)槔^承了Object, 沒什么其他卵用 filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } //postProcessPropertyValues方法已廢棄,被postProcessProperties替代 pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); }}上面代碼翻譯下大概就是:先執(zhí)行InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation方法回調(diào),然后再去執(zhí)行InstantiationAwareBeanPostProcessor#postProcessProperties,最后再去執(zhí)行applyPropertyValues()完成PropertyValue方式的依賴注入。這里有個(gè)大名鼎鼎的@Autowired、@Value方式的依賴注入,就是借助于InstantiationAwareBeanPostProcessor#postProcessProperties()方法實(shí)現(xiàn),這個(gè)實(shí)現(xiàn)類就是:AutowiredAnnotationBeanPostProcessor,簡(jiǎn)單看下依賴注入邏輯:
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { /** * 從緩存中找到此類的@Autowired、@Value注解元數(shù)據(jù),嘗試注入 * InjectionMetadata,持有待注入的元數(shù)據(jù)信息,執(zhí)行inject()方法,開始注入屬性或方法參數(shù)。 */ InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { //為beanName填充上屬性bean metadata.inject(bean, beanName, pvs); } catch (BeanCreationException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex); } return pvs;}這里有意義的代碼就兩行:
1、InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);獲取Bean中需要依賴注入注入的元素,封裝成一個(gè)InjectionMetadata對(duì)象,該對(duì)象有兩個(gè)重要屬性:
targetClass指定目標(biāo)對(duì)象的Class;Collection injectedElements :目標(biāo)對(duì)象中每個(gè)需要依賴注入的元素都會(huì)封裝成一個(gè)InjectedElement,然后存儲(chǔ)到該集合中。根據(jù)@Autowired/@Value注解到字段上還是方法上,InjectedElement又可以分為兩類:AutowiredFieldElement和AutowiredMethodElement。2、metadata.inject(bean, beanName, pvs);:這個(gè)方法內(nèi)部就是循環(huán),對(duì)每個(gè)依賴元素InjectedElement調(diào)用inject()方法
if (!elementsToIterate.isEmpty()) { for (InjectedElement element : elementsToIterate) { if (logger.isTraceEnabled()) { logger.trace("Processing injected element of bean "" + beanName + "": " + element); } element.inject(target, beanName, pvs); }}比如我們一般將@Autowired標(biāo)注到字段上,則這里會(huì)觸發(fā)AutowiredFieldElement#inject()方法執(zhí)行:
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Field field = (Field) this.member;//依賴注入字段 Object value;//存儲(chǔ)需要注入的值 if (this.cached) {//如果已被緩存,則直接先從緩存中獲取依賴注入值 value = resolvedCachedArgument(beanName, this.cachedFieldValue); } else {//還未被緩存過 //1.DependencyDescriptor:用于對(duì)該依賴注入描述信息 DependencyDescriptor desc = new DependencyDescriptor(field, this.required); desc.setContainingClass(bean.getClass()); Set autowiredBeanNames = new LinkedHashSet<>(1); Assert.state(beanFactory != null, "No BeanFactory available"); TypeConverter typeConverter = beanFactory.getTypeConverter(); try { /* 2.查找依賴注入的值 比如: @Autowired private TestService03 testService03; 這個(gè)value就是從IoC容器中查找到的TestService03對(duì)象 還比如:@Value("${spring.name}"),這個(gè)value就是從Spring上下文環(huán)境變量中解析出的spring.name變量值 */ value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); } catch (BeansException ex) { throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex); } //3.下面synchronized塊主要實(shí)現(xiàn)緩存功能,已被解析過的包裝成ShortcutDependencyDescriptor類型,上面resolvedCachedArgument對(duì)這種類型會(huì)特殊處理 synchronized (this) { if (!this.cached) { if (value != null || this.required) { this.cachedFieldValue = desc; registerDependentBeans(beanName, autowiredBeanNames); if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); if (beanFactory.containsBean(autowiredBeanName) && beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { this.cachedFieldValue = new ShortcutDependencyDescriptor( desc, autowiredBeanName, field.getType()); } } } else { this.cachedFieldValue = null; } this.cached = true; } } } //4.查找到的依賴值不為null,則使用反射方式注入,因?yàn)槭峭ㄟ^反射方式,所以@Autowired、@Value是不需要setter/getter方法也可以注入 if (value != null) { //通過反射方式將查找到的需要依賴注入的值設(shè)置到對(duì)象實(shí)例中 ReflectionUtils.makeAccessible(field); field.set(bean, value); }} InstantiationAwareBeanPostProcessor還有個(gè)子接口:SmartInstantiationAwareBeanPostProcessor,其定義如下:
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor { //推斷類型 @Nullable default Class> predictBeanType(Class> beanClass, String beanName) throws BeansException { return null; } //根據(jù)一定規(guī)則推斷出Bean中優(yōu)選的構(gòu)造方法 @Nullable default Constructor>[] determineCandidateConstructors(Class> beanClass, String beanName) throws BeansException { return null; } default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { return bean; }}SmartInstantiationAwareBeanPostProcessor接口有三個(gè)方法,在實(shí)例創(chuàng)建前智能判斷實(shí)例類型、智能判斷構(gòu)造函數(shù)、提起獲取暴露Bean引用,該接口主要是spring框架內(nèi)部使用,開發(fā)時(shí)很少去擴(kuò)展該接口。
這里主要注意第三個(gè)方法:getEarlyBeanReference(),這個(gè)擴(kuò)展方法主要與Spring中的循環(huán)依賴有關(guān)系。前面分析IoC容器啟動(dòng)時(shí)分析過:為了解決Spring中的循環(huán)依賴問題,在doCreateBean()方法內(nèi)部,會(huì)將剛創(chuàng)建還未來得及進(jìn)行依賴注入和初始化的半成品Bean提前暴露出去,addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));,注意這里不是直接將Bean暴露出去,而是通過() -> getEarlyBeanReference(beanName, mbd, bean)這句將Bean包裝成ObjectFactory類型再暴露出去。
這里的一個(gè)核心就是:為什么不直接暴露Bean,而是將Bean包裝成ObjectFactory再去暴露?將Bean包裝成ObjectFactory再去暴露,調(diào)用getObject()方法時(shí)會(huì)觸發(fā)SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference方法回調(diào)。
分析到這里,還不夠完善,因?yàn)槟憧赡軙?huì)問:那這個(gè)方法回調(diào)又可以給我們解決什么問題呢?
可以利用Spring AOP原理來回答這個(gè)問題,Spring AOP主要基于AnnotationAwareAspectJAutoProxyCreator這個(gè)類實(shí)現(xiàn),這個(gè)類實(shí)現(xiàn)了BeanPostProcessor接口,在postProcessAfterInitialization()方法中對(duì)創(chuàng)建完成的Bean采用動(dòng)態(tài)代理方式將增強(qiáng)邏輯織入進(jìn)去。
如果存在這樣情況:A依賴B,B同時(shí)依賴A,這就是所說的Spring循環(huán)依賴,但是如果我們對(duì)A采用了AOP增強(qiáng),這個(gè)過程會(huì)是怎樣情況呢?
init-method初始化方法后,postProcessAfterInitialization()執(zhí)行時(shí)會(huì)給A通過動(dòng)態(tài)代理方式織入增強(qiáng)邏輯;這時(shí),步驟3中給B注入的是A的原生對(duì)象,但是步驟6會(huì)給A創(chuàng)建一個(gè)代理對(duì)象,但是B中這時(shí)還是原生對(duì)象沒法改變,這就會(huì)導(dǎo)致有的依賴注入的是原生對(duì)象,有的依賴注入的是代理對(duì)象,會(huì)出現(xiàn)錯(cuò)亂問題。如何解決呢?這個(gè)就是SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference這個(gè)擴(kuò)展點(diǎn)作用。
A對(duì)象提前暴露時(shí),利用ObjectFactory包裝了一層,B對(duì)象在進(jìn)行依賴注入時(shí)獲取到對(duì)象A時(shí),不是直接返回A,而是觸發(fā)getEarlyBeanReference()方法執(zhí)行,AnnotationAwareAspectJAutoProxyCreator類在getEarlyBeanReference()方法中實(shí)現(xiàn)判斷A需要做動(dòng)態(tài)代理,則對(duì)A進(jìn)行動(dòng)態(tài)代理后返回,這時(shí)B中依賴注入的就不是原生對(duì)象。
總結(jié):SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference()方法是在循環(huán)依賴場(chǎng)景下,對(duì)提前暴露的Bean可以通過該擴(kuò)展點(diǎn)進(jìn)行處理。只有因?yàn)榇嬖谘h(huán)依賴,才會(huì)導(dǎo)致需要需要獲取那些提前暴露的Bean時(shí)才會(huì)觸發(fā)該擴(kuò)展點(diǎn),所以,理解這個(gè)擴(kuò)展點(diǎn)關(guān)鍵在于你對(duì)Spring循環(huán)依賴的理解。
DestructionAwareBeanPostProcessor是BeanPostProcessor子接口,其定義如下:
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor { //Bean銷毀前回調(diào)方法 void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException; //可以根據(jù)Bean進(jìn)行過濾,哪些Bean需要用到當(dāng)前這個(gè)回調(diào) default boolean requiresDestruction(Object bean) { return true; }}從名稱就可以看出,該擴(kuò)展主要用于Bean銷毀之前,回調(diào)時(shí)機(jī)在:DisposableBeanAdapter#destroy()
public void destroy() { //調(diào)用DestructionAwareBeanPostProcessor#postProcessBeforeDestruction,Bean銷毀之前回調(diào)接口 if (!CollectionUtils.isEmpty(this.beanPostProcessors)) { for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) { processor.postProcessBeforeDestruction(this.bean, this.beanName); } } ... ((DisposableBean) this.bean).destroy();//調(diào)用DisposableBean.destroy() ... }DestructionAwareBeanPostProcessor接口有個(gè)實(shí)現(xiàn)類InitDestroyAnnotationBeanPostProcessor,實(shí)現(xiàn)對(duì)@PreDestroy注解支持。該擴(kuò)展接口本身是比較簡(jiǎn)單的,后續(xù)分析Bean生命周期destroy流程整體梳理。
MergedBeanDefinitionPostProcessor
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor { void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName); //Spring5.1新增接口,實(shí)現(xiàn)BeanDefinition重置通知,一般該方法實(shí)現(xiàn)重置前清理metadata等元數(shù)據(jù)緩存 default void resetBeanDefinition(String beanName) { }}我們主要看下postProcessMergedBeanDefinition()方法調(diào)用時(shí)機(jī):
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { //1.創(chuàng)建對(duì)象 //2.執(zhí)行MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition回調(diào)方法 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } } //3.提前暴露Bean //4.populateBean(beanName, mbd, instanceWrapper); //5.exposedObject = initializeBean(beanName, exposedObject, mbd);}MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition發(fā)生在Bean剛創(chuàng)建完成,Bean還未提前暴露之前。MergedBeanDefinitionPostProcessor在Spring中有很多的應(yīng)用,比如:AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、InitDestroyAnnotationBeanPostProcessor等。這個(gè)擴(kuò)展的一般套路是和其它擴(kuò)展點(diǎn)一起使用,其起到一個(gè)幫手角色,postProcessMergedBeanDefinition將需要處理的注解信息解析成元數(shù)據(jù)信息緩存起來,其它擴(kuò)展點(diǎn)就可以從緩存中獲取需要處理的注解信息進(jìn)行處理。有關(guān)這擴(kuò)展點(diǎn)更多的情況會(huì)在后續(xù)案例分析中再詳細(xì)分析。
BeanFactoryPostProcessor和BeanPostProcessor是Spring提供的兩個(gè)最核心、最基礎(chǔ)的擴(kuò)展方式:一個(gè)面向IoC進(jìn)行擴(kuò)展,另一個(gè)面向Bean的創(chuàng)建流程進(jìn)行各種擴(kuò)展。BeanPostProcessor及其子類實(shí)現(xiàn)了對(duì)Bean創(chuàng)建過程中的各種擴(kuò)展:Bean創(chuàng)建前后、Bean初始化前后、獲取提前暴露對(duì)象前等等這些。Spring中大量注解簡(jiǎn)化了我們使用框架的復(fù)雜性,而這些注解很大一部分就是基于這些擴(kuò)展進(jìn)行處理,學(xué)習(xí)這些擴(kuò)展點(diǎn)可以幫助我們更好的熟悉Spring的運(yùn)行機(jī)理,同時(shí)可以在開發(fā)中幫助我們靈活的實(shí)現(xiàn)各種功能擴(kuò)展。
關(guān)鍵詞: