[英]Spring bean definition class name is null when using JavaConfig
我正在實現BeanFactoryPostProcessor
並且試圖提取Bean定義的類名:
@Component
public class MyFactory implements BeanFactoryPostProcessor{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
// 'null' when using JavaConfig, 'java.lang.String' when using XML
System.out.println(beanDefinition.getBeanClassName());
}
}
}
當我通過XML配置我的bean時,我得到的類名沒有任何問題:
<bean id="arbitraryString" class="java.lang.String"/>
<bean class="com.test.MyFactory"/>
但是,當我使用JavaConfig並在那里定義一個bean(用於演示的簡單String)時,類名將為null:
@Bean
public String arbitraryString () {
return "the bean definition class name will be null";
}
我嘗試搜索此內容,但無法理解我做錯了什么還是預期的行為。 除了加載上下文(無論是XML還是配置類)之外,我在main方法中沒有執行任何其他操作。
我已經研究了一下,我想我知道問題可能是什么(不確定我是否正確,或者我是否解釋正確)。 但是,這似乎是一個問題:
在JavaConfig類中定義bean會在春季之前初始化該類。 我認為這里的順序很重要:
它將選擇您的配置類,檢索所有@Bean注釋的方法,然后創建那些對象。
現在,我相信您要引用的“根bean”是一個實現類,以防您實例化該類。 這看起來很自然,但是在spring XML和spring javaconfig之間要有一個目標。
在xml中:
所有bean被定義為類。 通過調用該類的構造方法來實例化它們。
在JavaConfig中:
該Bean不再是獨立的Bean。 它被視為工廠bean。 因此,該bean實際上沒有根bean類,它有一個工廠bean和一個工廠方法。 如何從方法定義中設置根類? 您可以將root bean設置為類,但是在大多數類中都不能成立。 工廠可以返回返回類的任何實現,因此在創建BeanDefinition對象時,沒有可用的根bean。
可以通過將appconfig標記為靜態(工廠方法)來觀察此情況。 現在,沒有工廠bean,因為在掃描配置類時不會創建它。 這意味着,spring將使用CGI創建一個實現,它是root bean。 但是,這不是您期望的root bean。 例如,在我的測試中:
com.*.*.AppConfig$$EnhancerBySpringCGLIB$$1d5cc574
這是在創建靜態bean時獲得的輸出。
因此,總計:
JavaConfig的行為就像一個工廠,因此所創建的bean在定義定義時是未知的。
Xml定義良好,顯式設置了實現類,因此給出了一個根bean。
因為工廠不存在,所以需要生成靜態bean,但是仍然需要創建類。
希望對您有所幫助:)
-阿圖爾
編輯:最后的筆記,這是預期的行為:)
具有@Bean
Bean由ConfigurationClassBeanDefinitionReader
定義,並且Bean定義類為AnnotatedBeanDefinition
所以。 您可以從它的FactoryMethodMetadata
獲取類名
if(beanDefinition instanceof AnnotatedBeanDefinition) { // definition with @Bean Annotation cause this issue
MethodMetadata factoryMethodMetadata = ((AnnotatedBeanDefinition) beanDefinition).getFactoryMethodMetadata();
if (factoryMethodMetadata != null) {
className = factoryMethodMetadata.getReturnTypeName();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.