2015-02-06 90 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