2015-02-06 88 views
4

我正在使用Play 2.3和Java 8構建一個多模塊項目。根應用程序和每個模塊都有一個Global對象。但是我們如何知道Play只使用根應用程序中的一個Global對象。Play Framework:在多模塊項目中合併多個Global對象

簡化文件夾結構:

/root 
    /app 
     Global.java 
    /conf 
     application.conf 
    /subprojects 
     /user 
      /app 
       UserGlobal.java 
     /admin 
      /app 
       AdminGlobal.java 

放置在未命名的包中的所有全局類。

我用這樣的方式從子項目合併全局對象:在根中的根全球

1)宣佈配置變量application.conf

subprojects.with.globals="subprojectName1, subprojectName2, subprojectName3, ..." 

2)增加私有字段和私有方法.java

private List<GlobalSettings> subprojectGlobals = new ArrayList<>(); 

private void LoadSubprojectGlobals(Application app) 
    throws ClassNotFoundException, IllegalAccessException, InstantiationException 
{ 
    String subprojectNames = 
     app.configuration().getString("subprojects.with.globals"); 
    if (!subprojectNames.isEmpty()) 
    { 
     Class subprojectGlobalClass = null; 
     for (String subprojectName : subprojectNames.split(",")) 
     { 
      subprojectGlobalClass = Class.forName(
       WordUtils.capitalize(subprojectName.trim().toLowerCase()) + 
       "Global" 
      ); 
      subprojectGlobals.add(
       (GlobalSettings)subprojectGlobalClass.newInstance() 
      ); 
     } 
    } 
} 

3)將這樣的代碼放入Global.java

@Override 
public void onStart(Application app) 
{ 
    try 
    { 
     LoadSubprojectGlobals(app); 
    } 
    catch(Exception e) 
    { 
     new RuntimeException(e); 
    } 

    for(GlobalSettings subprojectGlobal: subprojectGlobals) 
    { 
     subprojectGlobal.onStart(app); 
    } 
} 

的OnStart事件處理現在,如果我們增加了一些新的子項目,我們必須根application.conf編輯subprojects.with.globals。如果我們想要處理更多的全局設置,我們需要覆蓋根目錄Global.java中的適當方法。

如果我們能夠根據根目錄onStart中的java代碼動態確定所有子項目名稱,這將會很酷。可能嗎?可能是從根目錄build.sbt或從Application對象?

UPDATE

我改變了我的項目申請@Mon魷魚的做法。

1)刪除了配置變量subprojects.with.globals從根application.conf

2)把所有子項目全球類轉換成全局包:

/subprojects 
    /user 
     /app 
      /globals 
       UserGlobal.java 
    /admin 
     /app 
      /globals 
       AdminGlobal.java 

3)增加的配置變量納入所有子項目CONF文件像

application.global= globals.UserGlobal 

4)已變更LoadSubprojectGlobals()執行:

private void LoadSubprojectGlobals(Application app) 
    throws ClassNotFoundException, IllegalAccessException, InstantiationException 
{ 
    Reflections reflections = new Reflections("globals"); 
    Set<Class<? extends GlobalSettings>> subprojectGlobalClasses = 
     reflections.getSubTypesOf(GlobalSettings.class); 

    for(Class subprojectGlobalClass : subprojectGlobalClasses) 
    { 
     subprojectGlobals.add(
      (GlobalSettings)subprojectGlobalClass.newInstance() 
     ); 
    } 
} 

現在,如果我們添加一些新的子項目,我們必須遵循一些有關添加Global類的約定,但我們不需要跟蹤子項目列表。

非常感謝。

回答

1

我不知道如何你的模塊/包的安排,但如果你使用org.reflections獲得play.GlobalSettings類的所有擴展的內容:

Reflections reflections = new Reflections("your.package");  
Set<Class<? extends GlobalSettings>> classes = reflections.getSubTypesOf(GlobalSettings.class) 
+0

非常感謝你。我嘗試了你的方法。它工作,我認爲它適合我。我將在明天更新我的帖子,以便更清楚地說明。 – 2015-02-08 18:26:35