Play Framework:在多模块项目中合并多个全局对象 [英] Play Framework: merging multiple Global objects in multi-module project

查看:165
本文介绍了Play Framework:在多模块项目中合并多个全局对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm building a multi-module project using Play 2.3 and Java 8. Root application and each module have a Global object. But how we know Play uses only one Global object from root application.

简化的文件夹结构:

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

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

All Global classes placed in unnamed package.

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

I use such way for merging Global objects from subprojects:

1) 根目录中声明的配置变量 application.conf

1) Declared configuration variable in 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) 将此类代码放入根目录 Global.java

3) Placed such code into onStart event handler in root Global.java

@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 中的适当方法.

Now if we add some new subproject we must edit subprojects.with.globals in root application.conf. And if we want to handle more global settings we need to override appropriate method in root Global.java.

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

It will be cool if we'll be able to determine all subproject names dynamically from java-code in root onStart. Is it possible? May be from root build.sbt or from Application object?

更新

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

I changed my project applying @Mon Calamari's approach.

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

1) Removed configuration variable subprojects.with.globals from root application.conf.

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

2) Put all subproject Global classes into globals package:

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

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

3) Added configuration variable into all subproject conf files like a

application.global= globals.UserGlobal

4) 更改了 LoadSubprojectGlobals() 实现:

4) Changed LoadSubprojectGlobals() implementation:

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

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

Now if we add some new subproject we must follow some conventions about adding Global class but we have no need to keep track sub projects list.

非常感谢.

推荐答案

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

I am not sure how your modules/packages are arranged, but what if you use org.reflections to get all extensions of play.GlobalSettings class:

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

这篇关于Play Framework:在多模块项目中合并多个全局对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆