2012-07-03 47 views
1

因此,我的一個配置類包括(測試/生產)DatabaseConfig類,正確的配置類可以通過活動配置文件選擇。但是,當DatabaseConfig類運行時,它的數據源ivar爲空。彈簧配置在創建bean之前不自動掛接?

我做了調試,我TestingDatabaseConfig的DataSource()方法DatabaseConfig的localContainerEntityManagerFactoryBean前的run()運行。

我想我的問題是,爲什麼沒有這方面的工作,它應該工作,我究竟做錯了什麼?

@Configuration 
@Profile({"testing-db", "production-db"}) 
@Import({TestingDatabaseConfig.class, ProductionDatabaseConfig.class}) 
@EnableTransactionManagement 
public class DatabaseConfig 
{ 
    @Resource 
    private DataSource dataSource; 

    @Bean(name = "entityManager") 
    public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean() 
    { 
     LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); 

     entityManagerFactoryBean.setDataSource(this.dataSource); 

     // other config 

     return entityManagerFactoryBean; 
    } 

    // ... other db related beans stuff ... 
} 

@Configuration 
@Profile("testing-db") 
public class TestingDatabaseConfig implements DatabaseConfigInterface 
{ 
    @Bean(name="dataSource") 
    public DataSource dataSource() 
    { 
     JDBCDataSource dataSource = new JDBCDataSource(); 
     dataSource.setDatabase("jdbc:hsqldb:mem:testing"); 
     dataSource.setUser("sa"); 

     return dataSource; 
    } 
} 

回答

2

當然他們不是在調用構造函數之前注入。

使用@PostConstruct。這裏有一個很好的例子:http://www.mkyong.com/spring/spring-postconstruct-and-predestroy-example/

+0

我不知道你是怎麼想的是要幫助。首先,構造函數與我無關,據我所知,它是我的DatbaseConfig類創建的,但在創建bean之前未創建自動裝配。 其次,施工順序是如何我希望,然後希望它。 DatabaseConfig(構造函數運行) - > TestingDatabaseConfig(構造函數運行) - > TestingDatabaseConfig(創建dataSource bean) - > DatabaseConfig(emf bean創建) 問題是我創建我的emf bean時沒有訪問dataSource bean 。 – dustins

+0

@dustins:如果你想把任何初始化代碼放到需要自動裝配字段的bean中,你必須創建一個方法並用'@ PostConstruct'對它進行註釋並在那裏進行初始化。原因很簡單:在構造函數中,所有自動裝配的字段都是'null'。 (當然除了基於構造函數的注入,但這是一個不同的故事)'@ PostConstruct'註釋的方法將被spring__after__注入調用,但__before__ bean將被用在框架中。 –

+0

我明白了,但我沒有 - 並沒有做任何內部的構造函數。我甚至沒有構造函數。我沒有看到如何將@PostConstruct放在任何東西上會有所幫助,我的bean方法已經在構造函數之後運行。我相信我只是不明白你想告訴我什麼。 – dustins

0

好的,所以我必須在第一次做這個錯誤,但解決方案是讓bean作爲參數自動裝配,而不是試圖將它們注入爲ivar。什麼,我不得不改變,以得到它的工作一個假差異......

- @Resource 
- private DataSource dataSource; 

- public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean() 
+ public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean(DataSource dataSource) 

- entityManagerFactoryBean.setDataSource(this.dataSource); 
+ entityManagerFactoryBean.setDataSource(dataSource); 

最終被比我試圖反正=做)

+0

第一個版本也可以,但是使用這個(基於構造函數的注入),你只是使用了不同的'樣式'。 –

0

看來,事情並不只是神奇的工作更清潔!如果您希望配置類具有自動裝配的ivars,則必須正確配置它,或者在這種情況下,讓另一個bean執行自動裝配。

您需要創建AutowiredAnnotationBeanPostProcessor豆。

@Bean 
public AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor() 
{ 
    return new AutowiredAnnotationBeanPostProcessor(); 
} 

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /> 
+1

更簡單的方法是在@Configuration類中放置一個@ComponentScan(basePackages = ..),默認情況下它會註冊一個AutoWiredAnnotationBeanProcessor –