簡體   English   中英

使用JavaConfig時Spring bean定義類名稱為null

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM