記錄一次因創(chuàng)建BeanDefinitonRegistryPostProcessor的Bean導(dǎo)致@Configuration注解類中屬性失效的問題

起因

事情的起因是這樣的艇棕,在開發(fā)基于nacos的動態(tài)線程池項目時,一開始選用的nacos-pring-context的版本為:0.2.2-RC1逗爹,版本中@NacosConfigListener注解的dataId與groupId不支持動態(tài)解析咽弦,于是相對其進行改造。
查看其源碼發(fā)現(xiàn)起作用的是NacosConfigListenerMethodProcessor類狐树。于是產(chǎn)生了一個想法重新創(chuàng)建創(chuàng)建一個CustomNacosConfigListenerMethodProcessor類注冊到容器中,將NacosConfigListenerMethodProcessor的BeanDefinition進行清除鸿脓,于是創(chuàng)建了一個ChangeDefinitionRegistryPostProcessor

public class ChangeDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        if(registry.containsBeanDefinition(NacosConfigListenerMethodProcessor.BEAN_NAME)){
            registry.removeBeanDefinition(NacosConfigListenerMethodProcessor.BEAN_NAME);
            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(CustomNacosConfigListenerMethodProcessor.class);
            // ROLE_INFRASTRUCTURE
            beanDefinitionBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            // Register
            registry.registerBeanDefinition(NacosConfigListenerMethodProcessor.BEAN_NAME, beanDefinitionBuilder.getBeanDefinition());
        }
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    }
}

然后在DynamicExecutorConfiguration中聲明該bean

@Configuration
@EnableNacos(globalProperties = @NacosProperties())
public class DynamicExecutorConfiguration implements ApplicationEventPublisherAware {
    public static final String DYNAMIC_EXECUTOR_PREFIX = "dynamic.executors";

    ApplicationEventPublisher publisher;

    @Value("${spring.application.name}")
    private String applicationName;

    @Bean
    ChangeDefinitionRegistryPostProcessor changeDefinitionRegistryPostProcessor(){
        return new ChangeDefinitionRegistryPostProcessor();
    }
}

現(xiàn)象

到此以為萬事大吉抑钟,然后去進行測試,突然發(fā)現(xiàn)項目報錯野哭,原因是@Value注解的applicationName字段為null在塔,我把ChangeDefinitionRegistryPostProcessor聲明bean的部分注釋掉,項目就可以正常啟動

探查原因

為什么在@ Configuration注解的類中聲明這個ChangeDefinitionRegistryPostProcessor的bean會導(dǎo)致屬性注入失敗呢虐拓,這里需要提前了解三個知識點

  1. @value注解的注入原理是什么心俗,在哪個類里面進行的,執(zhí)行時機是什么蓉驹,這個BeanPostPerocessor什么時候加入到BeanPostProcessor處理集合中的
  2. @Bean注解創(chuàng)建bean的過程是什么,這其中會對DynamicExecutorConfiguration產(chǎn)生什么影響
  3. ChangeDefinitionRegistryPostProcessor的執(zhí)行時機是什么時候
    下面來解決這三個問題
    第一個問題:@value注解的注入原理是什么揪利,在哪個類里面進行的态兴,執(zhí)行時機是什么?
    @value注解的代碼處理是在AutowiredAnnotationBeanPostProcessor的postProcessProperties方法進行處理的疟位,而方法的執(zhí)行時機是在bean的生命周期中屬性注入節(jié)點執(zhí)行的
    image.png

    image.png

    那什么時候加入到處理器集合中的呢瞻润?
    是在refresh方法的registerBeanPostProcessor(beanFactory)方法中加入處理器集合的
    image.png

    第二個問題:@Bean注解創(chuàng)建bean的過程是什么,這其中會對DynamicExecutorConfiguration產(chǎn)生什么影響甜刻?
    我們需要知道@Bean的bean的初始化的過程是利用的反射原理來實現(xiàn)绍撞,也就是說在實例化ChangeDefinitionRegistryPostProcessor這個Bean之前我們需要先創(chuàng)建DynamicExecutorConfiguration這個類的對象,也就是先創(chuàng)建DynamicExecutorConfiguration這個bean
    因此這里有一個點需要明白在創(chuàng)建ChangeDefinitionRegistryPostProcessor這個bean之前一定是需要先創(chuàng)建好DynamicExecutorConfiguration這個bean的
    第三個問題:ChangeDefinitionRegistryPostProcessor的執(zhí)行時機是什么時候得院?
    我們來看ChangeDefinitionRegistryPostProcessor屬于BeanDefinitionRegistryPostProcessor傻铣,因此他的執(zhí)行時機是在invokeBeanFactoryPostProcessor(beanFactory)方法中
    image.png

    需要特別提醒與在第一個問題中AutowiredAnnotationBeanPostProcessor是何時計入的BeanPostProcessor處理集合中的,對祥绞,是在后面的registerBeanPostProcessor(beanFactory)中非洲,這些意味著在執(zhí)行invokeBeanFacotryPostProcessors(beanFacotruy)時鸭限,容器中是沒有AutowiredAnnotationBeanPostProcessor這個處理Bean的

到此你是不是發(fā)現(xiàn)了什么?是的两踏,你猜的很多败京,當(dāng)DynamicExecutorConfiguration中聲明了ChangeDefinitionRegistryPostProcessor這個bean時,在執(zhí)行到invokeBeanFacotryPostProcessors(beanFactory)這個方法時會加載ChangeDefinitionRegistryPostProcessor這個bean梦染,而加載ChangeDefinitionRegistryPostProcessor的bean時赡麦,需要先加載DynamicExecutorConfiguration這個bean,因此在初始化單例bean
DynamicExecutorConfiguration的過程的在屬性注入populateBean()階段由于還沒有AutowiredAnnotationBeanPostProcessor這個bean帕识,導(dǎo)致無法完成@Value的屬性注入泛粹,又因為生成的是單例bean,后續(xù)再使用DynamicExecutorConfiguration這個bean時都是從一級緩存中獲取的渡冻,而這個bean是未完成屬性注入的bean
因此這也解釋了為什么DynamicExecutorConfiguration一旦聲明ChangeDefinitionRegistryPostProcessor這個bean時戚扳,就會導(dǎo)致屬性注入失敗的問題

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市族吻,隨后出現(xiàn)的幾起案子帽借,更是在濱河造成了極大的恐慌,老刑警劉巖超歌,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砍艾,死亡現(xiàn)場離奇詭異,居然都是意外死亡巍举,警方通過查閱死者的電腦和手機脆荷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來懊悯,“玉大人蜓谋,你說我怎么就攤上這事√糠郑” “怎么了桃焕?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長捧毛。 經(jīng)常有香客問我观堂,道長,這世上最難降的妖魔是什么呀忧? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任师痕,我火速辦了婚禮,結(jié)果婚禮上而账,老公的妹妹穿的比我還像新娘胰坟。我一直安慰自己,他們只是感情好福扬,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布腕铸。 她就那樣靜靜地躺著惜犀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪狠裹。 梳的紋絲不亂的頭發(fā)上虽界,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音涛菠,去河邊找鬼莉御。 笑死,一個胖子當(dāng)著我的面吹牛俗冻,可吹牛的內(nèi)容都是我干的礁叔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼迄薄,長吁一口氣:“原來是場噩夢啊……” “哼琅关!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起讥蔽,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤涣易,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后冶伞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體新症,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年响禽,在試婚紗的時候發(fā)現(xiàn)自己被綠了徒爹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡芋类,死狀恐怖隆嗅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情侯繁,我是刑警寧澤榛瓮,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布溯饵,位于F島的核電站嗤栓,受9級特大地震影響锣披,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜坝锰,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望重付。 院中可真熱鬧顷级,春花似錦、人聲如沸确垫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至翔冀,卻和暖如春导街,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背纤子。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工搬瑰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人控硼。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓泽论,卻偏偏與公主長得像,于是被迫代替她去往敵國和親卡乾。 傳聞我的和親對象是個殘疾皇子翼悴,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容