我正在使用 Play 2.3 和 Java 8 构建一个多模块项目。根应用程序和每个模块都有一个全局对象。但我们如何知道 Play 仅使用根应用程序中的一个全局对象。
简化的文件夹结构:
/root
/app
Global.java
/conf
application.conf
/subprojects
/user
/app
UserGlobal.java
/admin
/app
AdminGlobal.java
所有全局类都放置在未命名的包中。
我使用这种方式来合并子项目中的全局对象:
1)在root中声明配置变量应用程序配置文件
subprojects.with.globals="subprojectName1, subprojectName2, subprojectName3, ..."
2)在root中添加私有字段和私有方法全局.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)将这样的代码放入onStart根中的事件处理程序全局.java
@Override
public void onStart(Application app)
{
try
{
LoadSubprojectGlobals(app);
}
catch(Exception e)
{
new RuntimeException(e);
}
for(GlobalSettings subprojectGlobal: subprojectGlobals)
{
subprojectGlobal.onStart(app);
}
}
现在,如果我们添加一些新的子项目,我们必须编辑子项目.with.globals在根应用程序配置文件。如果我们想处理更多全局设置,我们需要重写 root 中适当的方法全局.java.
如果我们能够从根目录中的 java 代码动态确定所有子项目名称,那就太酷了onStart。是否可以?可能是从根开始构建.sbt或者来自应用程序对象?
UPDATE
我应用@Mon Calamari 的方法改变了我的项目。
1) 删除了配置变量子项目.with.globals从根开始应用程序配置文件.
2)将所有子项目Global类放入globals包裹:
/subprojects
/user
/app
/globals
UserGlobal.java
/admin
/app
/globals
AdminGlobal.java
3)将配置变量添加到所有子项目conf文件中,例如
application.global= globals.UserGlobal
4)改变加载子项目全局()执行:
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()
);
}
}
现在,如果我们添加一些新的子项目,我们必须遵循一些有关添加全局类的约定,但我们不需要跟踪子项目列表。
多谢。