【问题标题】:Play Framework: merging multiple Global objects in multi-module projectPlay Framework:在多模块项目中合并多个全局对象
【发布时间】:2015-02-06 11:52:52
【问题描述】:

我正在使用 Play 2.3 和 Java 8 构建一个多模块项目。根应用程序和每个模块都有一个全局对象。但是我们如何知道 Play 只使用了根应用程序中的一个全局对象。

简化的文件夹结构:

/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) 在根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) 将此类代码放入根 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);
    }
}

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

如果我们能够从根 onStart 中的 java-code 动态确定所有子项目名称,那就太棒了。是否可以?可能来自根 build.sbt 或来自 Application 对象?

更新

我应用@Mon Calamari 的方法更改了我的项目。

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

2) 将所有子项目的全局类放入globals包中:

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

3) 将配置变量添加到所有子项目的 conf 文件中,如 a

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()
        );
    }
}

现在如果我们添加一些新的子项目,我们必须遵循一些关于添加全局类的约定,但我们不需要跟踪子项目列表。

非常感谢。

【问题讨论】:

    标签: playframework


    【解决方案1】:

    我不确定你的模块/包是如何排列的,但是如果你使用org.reflections 来获取play.GlobalSettings 类的所有扩展:

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

    【讨论】:

    • 非常感谢。我试过你的方法。它有效,我认为它适合我。明天我将更新我的帖子以进行更多澄清。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 2015-02-26
    • 2013-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-28
    相关资源
    最近更新 更多