2013-10-01 56 views
1

我在寫一個Java EE 6應用程序,它利用Morphia將對象保存到MongoDB。我希望在必要時能夠使用DAO類@Inject,所以我創建了一個適當實例化DAO的Factory類。它看起來是這樣的:@用CDI注入Morphia DAO?

public class MyDAOFactory { 

    @Inject 
    private Datastore mongoDatastore = null; 

    /** 
    * Creates the DAO 
    */ 
    @Produces 
    @ApplicationScoped 
    public MyDAO createDAO() { 
     MyDAO dao = new MyDAO(
       this.mongoDatastore); 
     return dao; 
    } 
} 

代碼編譯罰款,但是當我在JBoss EAP 6.1運行我的應用程序它抱怨,因爲MyDAO沒有一個無參數的構造函數。我會添加一個,但Morphia BasicDAO類也沒有,所以我不知道它會以這種方式工作。

有沒有辦法將@Inject DAO實例加入我的EJB,Servlet等?或者我需要每次都手動實例化它?

+1

我不知道Morphia,但我猜* CDI需要無參數構造函數才能代理MyDAO組件。我認爲它也可能是一個受保護的(甚至是私人的)構造函數,所以它不會混淆你的公共接口。但是,如果這樣的構造函數不能寫出來(例如,因爲你不能爲父類['BasicDAO']構造函數提供適當的參數),那麼工廠是你唯一能想到的機會。 –

+0

是的,代理問題是爲什麼CDI抱怨缺乏無參數構造函數。但是,我認爲像這樣實施一個Factory類會解決它。情況並非如此嗎?有沒有更好的辦法? – Shadowman

回答

2

由於某種原因,CDI似乎需要MyDAO的無參數構造函數。也許是因爲你如何使用這個bean(可能的原因見規範第5章「客戶端代理」)。

無法創建一個默認的構造函數,因爲基類沒有一個,從我從code看到super構造直接利用其參數的個數。因此,從無參數構造函數中將null傳遞給super()將引發錯誤。

我的建議是創建一個界面(可選地延伸org.mongodb.morphia.dao.DAO),例如, MyDAOInterface,其所有公開的業務方法爲MyDAO。然後修改MyDAO實現這個接口,並改變你的製作人返回MyDAOInterface

public interface MyDAOInterface extends DAO {...} 

public class MyDAO implements MyDAOInterface { 
    // same implementation 
} 

public class MyDAOFactory { 
    @Inject 
    private Datastore mongoDatastore = null; 

    /** 
    * Creates the DAO 
    */ 
    @Produces 
    @ApplicationScoped 
    public MyDAOInterface createDAO() { 
     MyDAO dao = new MyDAO(this.mongoDatastore); 
     return dao; 
    } 
} 

順便說一句,面向接口編程有使你的代碼的可測試性的額外的好處,所以它是值得的次要麻煩。