Play Framework:在多模块项目中合并多个Global对象

时间:2015-02-06 11:52:52

标签: playframework

我正在使用Play 2.3和Java 8构建一个多模块项目.Root应用程序和每个模块都有一个Global对象。但我们如何知道Play只使用一个来自root应用程序的Global对象。

简化的文件夹结构:

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

所有全局类都放在未命名的包中。

我使用这种方式从子项目合并Global对象:

1)在root application.conf

中声明了配置变量
subprojects.with.globals="subprojectName1, subprojectName2, subprojectName3, ..."

2)在root Global.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)将此类代码放入root Global.java

中的 onStart 事件处理程序中
@Override
public void onStart(Application app)
{
    try
    {
        LoadSubprojectGlobals(app);
    }
    catch(Exception e)
    {
        new RuntimeException(e);
    }

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

现在,如果我们添加一些新的子项目,我们必须在root application.conf 中编辑 subprojects.with.globals 。如果我们想要处理更多的全局设置,我们需要覆盖root Global.java 中的适当方法。

如果我们能够从root onStart 中的java代码动态确定所有子项目名称,那将会很酷。可能吗?可能来自root build.sbt 或来自Application对象?

更新

我使用@Mon Calamari的方法改变了我的项目。

1)从root application.conf 中删除了配置变量 subprojects.with.globals

2)将所有子项目Global类放入 globals 包中:

/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 个答案:

答案 0 :(得分:1)

我不确定您的模块/软件包是如何排列的,但如果您使用org.reflections获取play.GlobalSettings类的所有扩展名怎么办?

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