playframework - starter - Play Framework: fusión de múltiples objetos globales en proyectos de múltiples módulos
play framework tutorial (1)
No estoy seguro de cómo se organizan sus módulos / paquetes, pero ¿qué org.reflections
si utiliza org.reflections
para obtener todas las extensiones de la clase play.GlobalSettings
:
Reflections reflections = new Reflections("your.package");
Set<Class<? extends GlobalSettings>> classes = reflections.getSubTypesOf(GlobalSettings.class)
Estoy construyendo un proyecto de varios módulos usando Play 2.3 y Java 8. La aplicación raíz y cada módulo tienen un objeto Global. Pero cómo sabemos Play utiliza solo un objeto Global desde la aplicación raíz.
Estructura simplificada de la carpeta:
/root
/app
Global.java
/conf
application.conf
/subprojects
/user
/app
UserGlobal.java
/admin
/app
AdminGlobal.java
Todas las clases globales colocadas en paquetes sin nombre.
Utilizo esa forma para fusionar objetos globales de subproyectos:
1) Variable de configuración declarada en la aplicación raíz.conf
subprojects.with.globals="subprojectName1, subprojectName2, subprojectName3, ..."
2) Se agregó campo privado y método privado en la raíz 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) Coloca dicho código en el controlador de eventos onStart en la raíz Global.java
@Override
public void onStart(Application app)
{
try
{
LoadSubprojectGlobals(app);
}
catch(Exception e)
{
new RuntimeException(e);
}
for(GlobalSettings subprojectGlobal: subprojectGlobals)
{
subprojectGlobal.onStart(app);
}
}
Ahora, si agregamos algún subproyecto nuevo, debemos editar los subproyectos.with.globals en la raíz application.conf . Y si queremos manejar más configuraciones globales, tenemos que anular el método apropiado en la raíz Global.java .
Sería fantástico si pudiéramos determinar dinámicamente todos los nombres de subproyectos desde java-code en root onStart . ¿Es posible? ¿Puede ser de root build.sbt o del objeto Application?
ACTUALIZAR
Cambié mi proyecto aplicando el enfoque de @Mon Calamari.
1) Se eliminaron los subproyectos de variable de configuración.with.globals de la raíz application.conf .
2) Coloque todas las clases globales de subproyecto en el paquete global:
/subprojects
/user
/app
/globals
UserGlobal.java
/admin
/app
/globals
AdminGlobal.java
3) Se agregó una variable de configuración en todos los archivos conf del subproyecto, como
application.global= globals.UserGlobal
4) Implementación modificada de 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()
);
}
}
Ahora, si agregamos algún subproyecto nuevo, debemos seguir algunas convenciones sobre cómo agregar clases globales, pero no necesitamos seguir la lista de subproyectos.
Muchas gracias.