Spring5源码 - 02 Bean和Java对象的区别与猜想验证BeanDefinition
文章目錄
- 問題
- 加載流程
- BeanFactoryPostProcessor的執(zhí)行時(shí)機(jī)
- Code
問題
Spring創(chuàng)建的Bean 和 我們提供的Class對(duì)象 有什么關(guān)系嗎? 一定是我們提供的這個(gè)對(duì)象實(shí)例嗎?
加載流程
BeanFactoryPostProcessor的執(zhí)行時(shí)機(jī)
結(jié)合上圖的流程,我們可以得出如下結(jié)論
中間這個(gè)部分,如果用戶實(shí)現(xiàn)了BeanFactoryPostProcessor接口,則可以對(duì)BeanDefinition進(jìn)行修改
Code
演示下這個(gè)功能
兩個(gè)類 一個(gè)可以被Spring掃描到的bean Artisan1 , 另外一個(gè)是普通的對(duì)象 Artisan2
package com.artisan.bd;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;@Component public class Artisan1 {@PostConstructpublic void init(){System.out.println("Artisan1 Created");} }標(biāo)注了 @Component
package com.artisan.bd;import javax.annotation.PostConstruct;public class Artisan2 {}普通對(duì)象
配置類
package com.artisan.bd;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;@Configuration @ComponentScan("com.artisan.bd") public class AppConfig { }測(cè)試類
package com.artisan.bd;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Test {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);System.out.println(ac.getBean(Artisan1.class));System.out.println(ac.getBean(Artisan2.class));} }同時(shí)我們也看到了 Artisan1這個(gè)對(duì)象,對(duì)應(yīng)的 BeanDefinition中的beanClass也是 Artisan1 .
那能改么? 能改成Artisan2嗎?
看了剛才的流程圖,我們知道如果實(shí)現(xiàn)了BeanFactoryPostProcessor接口,就可以修改BeanDefinition。
試試吧
package com.artisan.bd;import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.stereotype.Component;@Component public class ArtisanBeanFactoryPostProcessor implements BeanFactoryPostProcessor {/*** beanFactory 就是流程圖中的 bdmap BeanDefinition的map集合* @param beanFactory the bean factory used by the application context* @throws BeansException*/@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {// 取出A對(duì)應(yīng)的 beanDefinition -----> 這時(shí)候bd中存放的類是A.classGenericBeanDefinition beanDefinition = (GenericBeanDefinition) beanFactory.getBeanDefinition("artisan1");//ScannedGenericBeanDefinition beanDefinition1 = (ScannedGenericBeanDefinition) beanFactory.getBeanDefinition("artisan1");// 將bd中的beanclass修改為BbeanDefinition.setBeanClass(Artisan2.class);} }
使用實(shí)現(xiàn)類來接收 beanFactory.getBeanDefinition(“artisan1”) 的返回值,可用方法更多,接口中的方法太少,并且也木有我們要用的setBeanClassName 方法。
別忘了加@Component,不然spring無法掃描到,這個(gè)就不會(huì)生效 。
再此執(zhí)行剛才的代碼
同時(shí),通過name artisan1 獲取到的bean 其實(shí)是被修改后了的, 因?yàn)镾ping根據(jù)用戶提供的Artisan2, 實(shí)例化了Artisan2
再比如說修改scope
都明白了哈, 后面從源碼的角度分析 ~
總結(jié)
以上是生活随笔為你收集整理的Spring5源码 - 02 Bean和Java对象的区别与猜想验证BeanDefinition的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring5源码 - 01 BeanD
- 下一篇: Spring5源码 - 03 普通对象