2010-07-07 52 views
1

我有一個領域模型,由相當大的對象圖組成,其中領域對象正在創建其他領域對象等等。每個這些域對象都需要訪問少數幾個單例類型的助手對象,以實現各種目的。從域對象中訪問Spring單例程的好方法?

當我想起我已經使用Spring並且我可以使用Spring在應用程序啓動時實例化這些助手中的每一個時,我正要使用Java單例模式實現它們。

我的問題是如何從我的域對象中找到它們?這些都是通過「new」運算符創建的所有對象,並不受Spring的控制。

我在想我可以使用「getBean」方法,如果我有我的手在Spring應用程序上下文(我不這樣做) - 但這是好的表現?我需要這些東西要快...以及如何快速獲取應用程序上下文?

回答

1
public class SpringApplicationContextProvider implements ApplicationContextAware { 
    public void setApplicationContext(ApplicationContext ctx) 
     throws BeansException { 
     // Wiring the ApplicationContext into a static method 
     SpringApplicationContext.setApplicationContext(ctx); 
    } 
} 

,並定義爲SpringApplicationContext,

public class SpringApplicationContext { 
    private static ApplicationContext ctx; 

    public static void setApplicationContext(
     ApplicationContext applicationContext) { 
     ctx = applicationContext; 
    } 


    public static ApplicationContext getApplicationContext() { 
     return ctx; 
    } 

    private SpringApplicationContext(){ 

    } 
} 

定義SpringApplicationContextProvider在您的配置文件爲Spring Bean。現在可以使用此提供程序訪問應用程序上下文。

+0

工程很好。似乎奇怪的是,Spring並沒有內置這種功能,不是嗎? – HDave 2010-07-07 16:54:32

2

在典型的Spring應用程序,那種你所描述的通常是在業務服務層實現(即Spring管理的單身人士)跨實體邏輯,而不是域對象。 Spring應用程序中的域類往往是非常簡單的數據容器,可能有一些方法可以對它們封裝的數據執行基本操作,但是停止在複雜的對象圖之外管理複雜的對象圖。所以業務服務對象管理域對象,而不是相反。

如果你堅持要在你的域對象中注入單例,你可以使用AspectJ來實現。 Spring本身並不支持這一點。

+0

我聽到你在說什麼......但這聽起來像是你正在建議像服務方法那樣的「交易腳本」的貧血域模型。我是否誇大了這個?我努力避免DAO的一個巨大的同構樹去與我的域接口/類 - 通過讓頂級域對象處理較低的那些。想了解更多關於爲什麼這可能是一個糟糕的設計... – HDave 2010-07-07 04:28:47

+1

沒有需要的巨大的DAO樹。 :-)我通常每個相關的域組有一個DAO,而不是每個域類一個,並且每個DAO都從具有通用CRUD方法的基類繼承。但是,DAO不帶有業務邏輯,所以我認爲你的DAO策略與關於跨實體業務邏輯是集中在域類還是服務對象中的決定是正交的。 Spring鼓勵後者,其他框架(如Seam)鼓勵前者。就像所有的事情一樣,有一些權衡,最好的方法可能在中間的某個地方。 – 2010-07-07 15:26:30

+0

很好的解釋....謝謝。 – HDave 2010-07-07 20:56:58