2013-07-31 219 views
6

我有一個抽象類中,我試圖用@Value註釋從屬性文件注射用@Value屬性抽象類

public abstract class Parent { 
    @Value ("${shared.val}") 
    private String sharedVal; 

    public Parent() { 
     //perform common action using sharedVal 
    } 

} 

@Component 
public class ChildA extends Parent { 
    Param a1; 
    @Autowired 
    public ChildA (Param a1) { 
     super(); 
     this.a1 = a1; 
    } 
} 

我得到的NullPointerException注入值,因爲sharedVal未設置。我試圖在抽象類中添加@Component構造型,並且仍然是同樣的事情。

我可以用這種方式給抽象類注入價值嗎?如果不是如何做到這一點?

+1

你的子類是如何實例化的? – MattR

回答

18

我想你會發現sharedVal 設定,但是你想在構造函數中儘快使用它。在Spring使用@Value註釋注入值之前調用構造函數(必須調用)。

不是處理在構造函數中的價值,嘗試@PostContruct方法來代替,例如:

@PostConstruct 
void init() { 
    //perform common action using sharedVal 
} 

(或者,實現Spring的InitializingBean接口僅)。

+2

您應該觸摸任何注入值的最早時間是在後構建方法中;生命週期中較早的屬性狀態是未定義的(好吧,通常爲null或零爲迂腐)。 –

+0

謝謝,今天學到了一些新東西。 – ltfishie

+0

我怎麼能得到我的porperties文件中定義的值? @Value(「$ {shared.val}」) –

4

我可以用這種方式爲抽象類注入價值嗎?

抽象類不能實例化,所以沒有東西可以注入抽象類。相反,您應該將值注入到其具體的子類中。

確保您的具體子類被標記爲@Component原型,並在Spring中進行「組件掃描」。不需要抽象類上的@Component,因爲它不能被實例化。


更新:我終於弄清楚,您試圖訪問在構造函數中注入的價值卻發現未設置值。這是因爲Spring將在bean實例化後注入值。所以如果不使用構造函數注入,注入的值不能在構造函數中被訪問。按照Matt的建議,您可以使用@PostContruct或實施InitializingBean

以下節目,如果使用XML配置:

<context:property-placeholder location="classpath:xxxxx.properties" ignore-unresolvable="true" /> 


<bean id="parent" class="pkg.Parent" abstract="true" init-method="postConstruct"> 
    <property name="sharedVal" value="${shared.val}" /> 
</bean> 


<bean id="child" class="pkg.ChildA" parent="parent"> 

執行使用sharedVal您的共同行動中Parent#postConstruct()

+0

謝謝。我希望有辦法做到這一點,因爲通過XML,你可以創建一個bean作爲抽象。但是這是有道理的,因爲Spring無法初始化抽象類,所以不能注入值。我只能想到使用Property對象來加載我的屬性文件,並獲得密鑰。我希望通過使用@Value註釋來避免這種情況 – ltfishie

+1

我認爲這個答案有誤導性 - 當你使用自動裝配時,Spring實際上會爲抽象基類中定義的屬性注入值。 – MattR

+0

@MattR。是的。 Spring將抽象類中定義的屬性的值注入到具體的子類中,但不會抽象類中的抽象類無法實例化。請讓我知道我認爲哪部分答案是誤導性的。 –