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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

Spring的9处调用后置处理器

發(fā)布時(shí)間:2024/3/13 javascript 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring的9处调用后置处理器 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在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è)后面在分析。

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// Make sure bean class is actually resolved at this point.if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;}

因?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

  • CommonAnnotationBeanPostProcessor:這個(gè)是MergedBeanDefinitionPostProcessor 一個(gè)重要的子類,在這個(gè)類中
  • public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);//主要記錄生命周期方法InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);//記錄@Resource metadatametadata.checkConfigMembers(beanDefinition);}

    可見主要是為了后面的流程進(jìn)行的一些輔助動(dòng)作。

  • AutowiredAnnotationBeanPostProcessor:另外一個(gè)重要的子類。
  • public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);//記錄@AutoWired medatametadata.checkConfigMembers(beanDefinition);}

    還是為了后面的流程進(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)題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。