Play Framework:在多模块项目中合并多个全局对象
Play Framework: merging multiple Global objects in multi-module project
我正在使用 Play 2.3 构建一个多模块项目,Java 8. 根应用程序和每个模块都有一个全局对象。但是我们怎么知道 Play 仅使用根应用程序中的一个全局对象。
简化的文件夹结构:
/root
/app
Global.java
/conf
application.conf
/subprojects
/user
/app
UserGlobal.java
/admin
/app
AdminGlobal.java
所有全局 classes 都放在未命名的包中。
我使用这种方式从子项目中合并全局对象:
1) 在根目录中声明配置变量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
中的 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 代码动态确定所有子项目名称,那将会很棒。可能吗?可能来自 root build.sbt 或来自 Application object?
更新
我使用@Mon Calamari 的方法更改了我的项目。
1) 从根 application.conf.
中删除了配置变量 subprojects.with.globals
2) 将所有子项目 Global classes 放入 globals package:
/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()
);
}
}
现在如果我们添加一些新的子项目,我们必须遵循一些关于添加全局的约定 class 但我们不需要跟踪子项目列表。
非常感谢。
我不确定你的 modules/packages 是如何排列的,但是如果你使用 org.reflections
来获取 play.GlobalSettings
的所有扩展名怎么办 class:
Reflections reflections = new Reflections("your.package");
Set<Class<? extends GlobalSettings>> classes = reflections.getSubTypesOf(GlobalSettings.class)
我正在使用 Play 2.3 构建一个多模块项目,Java 8. 根应用程序和每个模块都有一个全局对象。但是我们怎么知道 Play 仅使用根应用程序中的一个全局对象。
简化的文件夹结构:
/root
/app
Global.java
/conf
application.conf
/subprojects
/user
/app
UserGlobal.java
/admin
/app
AdminGlobal.java
所有全局 classes 都放在未命名的包中。
我使用这种方式从子项目中合并全局对象:
1) 在根目录中声明配置变量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
中的 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 代码动态确定所有子项目名称,那将会很棒。可能吗?可能来自 root build.sbt 或来自 Application object?
更新
我使用@Mon Calamari 的方法更改了我的项目。
1) 从根 application.conf.
中删除了配置变量 subprojects.with.globals2) 将所有子项目 Global classes 放入 globals package:
/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()
);
}
}
现在如果我们添加一些新的子项目,我们必须遵循一些关于添加全局的约定 class 但我们不需要跟踪子项目列表。
非常感谢。
我不确定你的 modules/packages 是如何排列的,但是如果你使用 org.reflections
来获取 play.GlobalSettings
的所有扩展名怎么办 class:
Reflections reflections = new Reflections("your.package");
Set<Class<? extends GlobalSettings>> classes = reflections.getSubTypesOf(GlobalSettings.class)