javascript
Spring的9处调用后置处理器
在Sping的整個(gè)生命周期中,有9個(gè)地方調(diào)用后置處理器。這些后置處理器是spring實(shí)現(xiàn)自定義功能或者擴(kuò)展spring的核心所在
一、實(shí)例化前
該方法屬于InstantiationAwareBeanPostProcessor后置處理器
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {@Nullabledefault Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {return null;}default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {return true;}@Nullabledefault PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)throws BeansException {return null;}@Deprecated@Nullabledefault PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {return pvs;}}該方法的意思其實(shí)也體現(xiàn)到名字上了,就是在實(shí)例化之前做些什么。
如果該方法返回非空,代表整個(gè)創(chuàng)建流程提前結(jié)束,也就是說(shuō)后面什么屬性設(shè)置,bean的初始化等等都不會(huì)執(zhí)行了,所以重寫該方法一定要謹(jǐn)慎。這個(gè)方法一般會(huì)和 applyBeanPostProcessorsAfterInitialization后置結(jié)處理器結(jié)合使用,這個(gè)處理可是實(shí)現(xiàn)aop的核心,這個(gè)后面在分析。
因?yàn)槿绻阍赼pplyBeanPostProcessorsBeforeInstantiation中返回非空后,后面spring的流程就不會(huì)走了,但是如果你有個(gè)切面是想代理這個(gè)類,那就沒(méi)有辦法了,所以applyBeanPostProcessorsBeforeInstantiation返回非空后會(huì)調(diào)用applyBeanPostProcessorsAfterInitialization執(zhí)行aop代理
至于網(wǎng)上說(shuō)的說(shuō)法:
如果這里出現(xiàn)了aop的切面類,就會(huì)有InstantiationAwareBeanPostProcessor的子處理器進(jìn)行類的過(guò)濾,出現(xiàn)@AspectJ的類標(biāo)記為不需要代理的類,會(huì)被放入map中我目前不理解,我自己寫了一個(gè)切面類,結(jié)果還是和正常類走相同的流程。
二、實(shí)例bean前決定構(gòu)造器
在createBeanInstance中的方法determineConstructorsFromBeanPostProcessors中會(huì)調(diào)用SmartInstantiationAwareBeanPostProcessor 后置處理器的determineCandidateConstructors方法。
2.1 SmartInstantiationAwareBeanPostProcessor
該構(gòu)造器主要就是為了預(yù)測(cè)最終bean的類型(predicting the eventual type of a processed bean)。
2.2 determineCandidateConstructors
該方法也是此處構(gòu)造器的真正要做的事情。就是為了決定實(shí)例化bean的構(gòu)造器
private DeptService service;public DeptController(@Autowired DeptService service){this.service = service; }比如這種情況,肯定不走默認(rèn)的構(gòu)造函數(shù),spring就會(huì)在determineCandidateConstructors中決定出這個(gè)有參數(shù)的構(gòu)造器,然后創(chuàng)建實(shí)例的時(shí)候回檢查參數(shù)是否有@Autowired的,在構(gòu)造的時(shí)候就會(huì)把service給創(chuàng)建好
三、剛創(chuàng)建好實(shí)例之后
在createBeanInstance之后,這個(gè)時(shí)候bean的屬性、初始化方法等等都沒(méi)有創(chuàng)建好,基本屬于空白對(duì)象。然后在方法applyMergedBeanDefinitionPostProcessors中執(zhí)行類MergedBeanDefinitionPostProcessor的后置處理
3.1 MergedBeanDefinitionPostProcessor
這個(gè)類主要用來(lái)更改或者豐富bean的定義的元數(shù)據(jù)信息。
3.2 方法postProcessMergedBeanDefinition
可見主要是為了后面的流程進(jìn)行的一些輔助動(dòng)作。
還是為了后面的流程進(jìn)行的一些輔助動(dòng)作。
四、解決循環(huán)依賴
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {Object exposedObject = bean;if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);}}}return exposedObject;}上面這段源碼是在創(chuàng)建好bean后,如果開啟了循環(huán)依賴,那么會(huì)執(zhí)行
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));這個(gè)時(shí)候就來(lái)到了主角 getEarlyBeanReference這里。
可見該后置處理器屬于SmartInstantiationAwareBeanPostProcessor,這里到底是做什么呢?
4.1 AbstractAutoProxyCreator
改具體子類實(shí)現(xiàn)了SmartInstantiationAwareBeanPostProcessor接口。
public Object getEarlyBeanReference(Object bean, String beanName) {Object cacheKey = getCacheKey(bean.getClass(), beanName);this.earlyProxyReferences.put(cacheKey, bean);return wrapIfNecessary(bean, beanName, cacheKey);}這個(gè)代碼就是返回aop代碼的代碼。 所以該后置處理器有個(gè)功能就是返回aop的代理
五、實(shí)例化后
在屬性填充方法populateBean中
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {continueWithPropertyPopulation = false;break;}}}}改后置處理器來(lái)自InstantiationAwareBeanPostProcessor,調(diào)用其中的postProcessAfterInstantiation
改方法功能也簡(jiǎn)單,就是判斷是否進(jìn)行屬性注入。
六 設(shè)置屬性前
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) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {return;}}pvs = pvsToUse;}}改后置處理器用在 在工廠將給定的屬性值應(yīng)用到給定bean之前,對(duì)給定的屬性值進(jìn)行后處理。你可以進(jìn)行一些檢查,比如某個(gè)屬性是 “required”的,但是這個(gè)屬性需要的引用卻是空,這個(gè)時(shí)候可以進(jìn)行一些檢查工作。還有dubbo的注解 @DubboReference這個(gè)注解,就是在此處 替換需要注入的類來(lái)實(shí)現(xiàn)的。
七 執(zhí)行初始化方法前
if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}改代碼是在方法initializeBean中調(diào)用的。applyBeanPostProcessorsBeforeInitialization詳細(xì)調(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;}可以看到他的引用是接口BeanPostProcessor這個(gè)接口屬于頂級(jí)接口,他的子類太多了,其中有個(gè)出名的是CommonAnnotationBeanPostProcessor 該類的結(jié)構(gòu)圖是
其中他的父類InitDestroyAnnotationBeanPostProcessor是個(gè)重點(diǎn)角色,在改類中的postProcessBeforeInitialization方法中就執(zhí)行了大名鼎鼎的 @PostConstruct 注解的方法。
八 執(zhí)行初始化方法后
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;}鼎鼎大名的aop就是在這里進(jìn)行實(shí)現(xiàn)的。具體的后置處理器是AbstractAutoProxyCreator
九 銷毀bean容器的時(shí)候調(diào)用
具體后置處理器InitDestroyAnnotationBeanPostProcessor
然后調(diào)用的方法是postProcessBeforeDestruction
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());try {metadata.invokeDestroyMethods(bean, beanName);}catch (InvocationTargetException ex) {String msg = "Destroy method on bean with name '" + beanName + "' threw an exception";if (logger.isDebugEnabled()) {logger.warn(msg, ex.getTargetException());}else {logger.warn(msg + ": " + ex.getTargetException());}}catch (Throwable ex) {logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'", ex);}}什么是destory方法呢,被javax.annotation.PreDestroy 注解的的方法。
總結(jié)
以上是生活随笔為你收集整理的Spring的9处调用后置处理器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ChatGpt常用指令大全
- 下一篇: gradle idea java ssm