java - Cargue los granos de primavera de los archivos groovy personalizados en la aplicación Grails
spring spring-dsl (4)
Intentando cargar los granos de primavera del archivo groovy personalizado en Grails 2.3.7.
Sé que esta pregunta se ha formulado antes, pero después de horas de búsqueda, no puedo encontrar un enfoque coherente que cargue desde la ruta de clases.
La meta
- Modular
resources.groovy
en múltiples archivos de recursos personalizados - Coloque archivos de recursos personalizados en la ubicación estándar:
grails-app/conf/spring
- Use el complemento para hacer la magia; minimizar gastos generales
Intentó...
//## grails-app/conf/spring/MyBeansConfig.groovy
beans {
testsvc(TestService){
msg = ''hello''
}
}
Nota anterior, estoy usando beans {}
, not beans = {}
, aparentemente hace la diferencia:
recursos.groovy
Esto funciona...
beans = {
loadBeans ''file:C://Proj/Test1/grails-app//conf//spring//MyBeansConfig.groovy''
}
... y de acuerdo con los documentos , esto también debería, pero no:
importBeans("classpath:*MyBeansConfig.groovy")
ACTUALIZACIÓN - OPCIONES DE TRABAJO
(trabajando para Grails 2.3.7)
Opción 1: (src / java)
Siguiendo el consejo de lukelazarovic , este enfoque funciona ya que Grails automáticamente copia (no compila) archivos groovy en src/java
a classpath; funciona bien en eclipse y con despliegue de guerra:
//bean config files here
src/java/MyBeansConfig.groovy
src/java/FooBeansConfig.groovy
//resources.groovy
loadBeans(''classpath*:*BeansConfig.groovy'')
Opciones 2: (grails-app / conf / spring)
Este enfoque permite archivos de configuración de beans personalizados en grails-app/conf/spring
(créditos a ideascultor y mark.esher )
//bean config files here
grails-app/conf/spring/MyBeansConfig.groovy
//## resources.groovy
//for eclipse/local testing
loadBeans(''file:./grails-app/conf/spring/*BeansConfig.groovy'')
//for WAR/classpath
loadBeans(''classpath*:*BeansConfig.groovy'')
//## BuildConfig.groovy
grails.war.resources = { stagingDir, args ->
copy(todir: "${stagingDir}/WEB-INF/classes/spring") {
fileset(dir:"grails-app/conf/spring") {
include(name: "*BeansConfig.groovy")
exclude(name: "resources.groovy")
exclude(name: "resources.xml")
}
}
}
Opciones 3: (Complemento personalizado)
Si está utilizando complementos personalizados, este enfoque es ideal; la configuración de la placa de la caldera se refactoriza en el complemento:
Configuración del complemento
//## scripts/_Events.groovy
eventCreateWarStart = { warName, stagingDir ->
def libDir = new File("${stagingDir}/WEB-INF/classes/spring")
ant.copy(todir: libDir) {
fileset(dir:"grails-app/conf/spring") {
include(name: "*BeansConfig.groovy")
exclude(name: "resources.groovy")
exclude(name: "resources.xml")
}
}
}
//## MyGrailsPlugin.groovy
def doWithSpring = {
loadBeans(''file:./grails-app/conf/spring/*BeansConfig.groovy'')
loadBeans(''classpath*:*BeansConfig.groovy'')
}
Aplicación Grails
¡Sin configuración! ... solo crea tus archivos de configuración de *BeansConfig.groovy
usando la convención *BeansConfig.groovy
, ¡listo!
//bean config files here
grails-app/conf/spring/MyBeansConfig.groovy
Actualización 24/09/2015
Encontró algunos problemas con la opción 3:
- carga de archivos de recursos duplicados
- recursos de primavera no configurados correctamente para
test-app
Nos las arreglamos para solucionar el problema anterior de manera que los archivos de recursos en grails-app/conf/spring
funcionen de la misma manera al ejecutar Grails en eclipse, WAR, test-app, etc.
Primer paso: creamos una clase para tener más control sobre la localización y carga de los archivos de recursos; esto era necesario ya que algunos archivos se cargaban más de una vez debido a los beans con referencias cruzadas. Estamos utilizando un complemento para encapsular esta funcionalidad, por lo que esta clase vive en ese complemento:
class CustomResourceLoader {
static loadSpringBeans(BeanBuilder bb){
def files = [''*''] //load all resource files
//match resources using multiple methods
def matchedResourceList = []
files.each {
matchedResourceList +=
getPatternResolvedResources("file:./grails-app/conf/spring/" + it + ".groovy").toList()
matchedResourceList +=
getPathMatchedResources("classpath*:spring/" + it + ".groovy").toList()
}
//eliminate duplicates resource loaded from recursive reference
def resourceMap = [:]
matchedResourceList.each{
if(it) resourceMap.put(it.getFilename(), it)
}
//make resources.groovy first in list
def resourcesFile = resourceMap.remove("resources.groovy")
if(!resourcesFile)
throw new RuntimeException("resources.groovy was not found where expected!")
def resourcesToLoad = [resourcesFile]
resourceMap.each{k,v -> resourcesToLoad << v }
log.debug("Spring resource files about to load: ")
resourcesToLoad.each{ bb.loadBeans(it) }
}
static def getPatternResolvedResources(path){
ResourcePatternResolver resourcePatternResolver =
new PathMatchingResourcePatternResolver();
return resourcePatternResolver.getResources(path);
}
static def getPathMatchedResources(path){
return new PathMatchingResourcePatternResolver().getResources(path)
}
}
Se BeansConfig.groovy
sufijo BeansConfig.groovy
; La generación WAR ahora recoge los recursos en grails-app/conf/spring
plugin, _Events.groovy
eventCreateWarStart = { warName, stagingDir ->
def libDir = new File("${stagingDir}/WEB-INF/classes/spring")
ant.copy(todir: libDir) {
fileset(dir:"grails-app/conf/spring") {
include(name: "*.groovy")
exclude(name: "resources.xml")
}
}
}
}
En el archivo de definición del complemento, llame al cargador desde doWithSpring()
, pasando BeanBuilder
(el delegado) como argumento (muy importante):
def doWithSpring = {
CustomResourceLoader.loadSpringBeans(delegate)
}
Eso es todo, no hay ningún requisito para los usuarios del complemento, aparte de crear archivos de recursos personalizados en grails-app/conf/spring
Tuve el mismo problema con los archivos XML personalizados en Grails 2.1.2.
Tener recursos XML en grails-app/conf/spring
no funcionó en el entorno de producción AFAIR.
Para hacerlo funcionar tanto en entornos de desarrollo como de producción, finalmente coloqué los recursos en src/java
. Creo que puede lograr el mismo resultado al poner sus archivos groovy en src/groovy
.
Tuve un problema similar hace unos días, con un archivo de configuración groovy que agregué a grails-app/conf
. Si bien esto funciona con otros recursos (se copian y están disponibles en el classpath), el problema con el archivo groovy era simplemente que se compiló y se incluyó el archivo de clase, es decir, no el archivo groovy en sí.
No encontré ninguna buena documentación sobre cómo se debe hacer esto y, finalmente, solo lo agregué a web-app/WEB-INF/classes
. Los archivos Groovy colocados aquí se copiarán (no compilarán) y estarán disponibles en classpath.
También podemos importar frijoles de diferentes archivos groovy / xml de la siguiente manera: - use lo siguiente en resources.groovy -
archivo importBeans: camel-beans.groovy ''O importBeans ('' classpath: /camel-config.xml '')
Coloque camel-beans.groovy junto con resources.groovy y proporcione el paquete como "paquete de primavera" para el primer caso, de lo contrario colóquelo en el classpath de la aplicación web y use la segunda forma para hacerlo.
Si sus recursos.groovy está en la ruta siguiente
grails-app/conf/spring/resources.groovy
y tus camel-beans.groovy está en el camino siguiente
grails-app/conf/spring/camel-beans.groovy
luego puede hacer referencia a camel-beans.groovy en el archivo resources.groovy agregando la siguiente línea en resources.groovy
importBeans(''file:**/camel-beans.groovy'')