【发布时间】: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