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