Spring5源码 - 02 Bean和Java对象的区别与猜想验证BeanDefinition
文章目錄
- 問題
- 加載流程
- BeanFactoryPostProcessor的執行時機
- Code
問題
Spring創建的Bean 和 我們提供的Class對象 有什么關系嗎? 一定是我們提供的這個對象實例嗎?
加載流程
BeanFactoryPostProcessor的執行時機
結合上圖的流程,我們可以得出如下結論
中間這個部分,如果用戶實現了BeanFactoryPostProcessor接口,則可以對BeanDefinition進行修改
Code
演示下這個功能
兩個類 一個可以被Spring掃描到的bean Artisan1 , 另外一個是普通的對象 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");} }標注了 @Component
package com.artisan.bd;import javax.annotation.PostConstruct;public class Artisan2 {}普通對象
配置類
package com.artisan.bd;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;@Configuration @ComponentScan("com.artisan.bd") public class AppConfig { }測試類
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));} }同時我們也看到了 Artisan1這個對象,對應的 BeanDefinition中的beanClass也是 Artisan1 .
那能改么? 能改成Artisan2嗎?
看了剛才的流程圖,我們知道如果實現了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對應的 beanDefinition -----> 這時候bd中存放的類是A.classGenericBeanDefinition beanDefinition = (GenericBeanDefinition) beanFactory.getBeanDefinition("artisan1");//ScannedGenericBeanDefinition beanDefinition1 = (ScannedGenericBeanDefinition) beanFactory.getBeanDefinition("artisan1");// 將bd中的beanclass修改為BbeanDefinition.setBeanClass(Artisan2.class);} }
使用實現類來接收 beanFactory.getBeanDefinition(“artisan1”) 的返回值,可用方法更多,接口中的方法太少,并且也木有我們要用的setBeanClassName 方法。
別忘了加@Component,不然spring無法掃描到,這個就不會生效 。
再此執行剛才的代碼
同時,通過name artisan1 獲取到的bean 其實是被修改后了的, 因為Sping根據用戶提供的Artisan2, 實例化了Artisan2
再比如說修改scope
都明白了哈, 后面從源碼的角度分析 ~
總結
以上是生活随笔為你收集整理的Spring5源码 - 02 Bean和Java对象的区别与猜想验证BeanDefinition的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring5源码 - 01 BeanD
- 下一篇: java美元兑换,(Java实现) 美元