2013-07-23 66 views
1

這可能是一個非常新手的問題,但我已經搜索過,或者我在理解上存在很大差距,或者我做了一些我無法弄清楚的錯誤。將數據源bean彈出注入或自動裝入類

在這裏我的上下文文件是摘錄

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="${datasource.driverClassName}" /> 
    <property name="url" value="${datasource.url}" /> 
    <property name="username" value="${datasource.username}" /> 
    <property name="password" value="${datasource.password}" /> 
</bean> 

<bean id="myBeanOne" class="a.b.c.myBeanOne"> 
     <property name="dataSource" ref="dataSource" /> 
</bean> 

現在myBeanOne我:

private DataSource dataSource; 

private JdbcTemplate jdbcTemplate; 

@Autowired 
public void setDataSource (DataSource dataSource) { 
    this.jdbcTemplate = new JdbcTemplate(dataSource); 
} 

public void myMethod() { 
    String sql = "'My generic SQL update query'"; 
    try { 
     this.jdbcTemplate.update(sql); 
    } catch (org.springframework.dao.EmptyResultDataAccessException ex) { 
    } 
    System.exit(0); 
} 

,當我試圖在那裏的setDataSource調用我得到這個錯誤的行執行此:

ERROR org.springframework.integration.handler.LoggingHandler 
    org.springframework.integration.MessageHandlingException: 
     java.lang.NullPointerException 

就行了:this.jdbcTemplate.update(sql);

我試過可能有十種不同的配置來使這個工作,但我似乎無法做到這一點。任何幫助表示讚賞,謝謝。

編輯:按Luiggi的評論:

//in yet another classes run method 
myBeanOne bOne = SomeOtherClass.create(); //just returns new myBeanOne 
bOne.myMethod(); 

無論SomeOtherClass或該類被列爲在上下文豆或在任何情況下存在。

我知道這是一個非常基本的問題,但我正在努力。

謝謝你的耐心等待。

+0

您錯過了主要問題:您如何調用'MyBeanOne#myMethod'? –

+0

正從另一個類(不在上下文文件中)調用它。 –

+0

檢查是否在堆棧跟蹤中看到任何錯誤,如果數據庫連接未建立,則會發生此錯誤。除此之外,我沒有看到代碼問題。 – Phani

回答

5

正如評論中指出的那樣,問題在於您手動創建bean而不是讓Spring容器創建它。基本上,你這樣做:

new MyBeanOne() 

所以Spring容器不能注入任何您所配置的領域的因而是null例如jdbcTemplate字段。有一些解決方案,以這樣的:

  1. 將您SomeOtherClass到由Spring容器管理的bean並讓它注入MyBeanOne實例(可能使用@Autowired註釋)。

  2. 如果後一種方法無法做到的,因爲你需要手動創建豆,你可以手動創建bean如下所示:How to create spring beans dynamically?

    但這種實現使得你硬編碼的春天某處配置文件名並在代碼中使用它。因此,更好的方法將是選項3.

  3. 看看這個解決方案:Creating New Spring Beans on Demand,在這裏你創建一個客戶端抽象類,用Spring將實現的方法來檢索你的Spring託管bean的一個新實例。


我發現另一種方式利用@Configurable註釋來處理這個問題。通過使用這個註解來裝飾你的bean,你可以按需創建一個新的bean實例,Spring將爲你管理Spring注入的bean。但爲了實現這一點,Spring需要在幕後使用方面,並且應該激活項目的方面使用。的解釋是很長,所以我提供了深入這個解決方案說明鏈接:

注意,爲了使此功能,你必須加一個Java代理啓動JVM時,將在運行時使用方面編織類。

+0

非常感謝您的回覆! –

0

NullPointerException on the line: this.jdbcTemplate.update(sql);

如果NPE實際上是在該行,然後this.jdbcTemplate顯然是null。如果這是真的,那麼:

  • setDataSource(...)方法不會被調用的春天,可能是因爲@Autowired是不對的莫名其妙。添加System.out.println(...)或在setDataSource中放置調試斷點以查看它是否被調用會很容易。

  • 如果它被調用,那麼也許有不止一個a.b.c.myBeanOne實例?你確定從Spring上下文中的另一個類中調用實例嗎?在setDataSource中放置一個斷點,並注意對象引用ID爲this。然後在this.jdbcTemplate.update(...)行上放置一個斷點,並確保this reference-id相同。