Cargue frijoles de primavera de archivos personalizados de Groovy en la aplicación Grails
Intentando cargar frijoles de primavera desde un archivo groovy personalizado en Grails2.3.7.
Sé que esta pregunta se ha hecho antes, pero después de horas de búsqueda, no puedo encontrar un enfoque consistente que se cargue desde el classpath.
resources.groovy
en múltiples archivos de recursos personalizadosPonga los archivos de recursos personalizados en la ubicación estándar:grails-app/conf/spring
Use el complemento para hacer la magia; minimizar los gastos generalesIntentó...//## grails-app/conf/spring/MyBeansConfig.groovy
beans {
testsvc(TestService){
msg = 'hello'
}
}
Nota anterior, estoy usandobeans {}
nobeans = {}
, aparentemente hace la diferencia:
recursos.groovy
Esto funciona...
beans = {
loadBeans 'file:C:\\Proj\Test1\grails-app\\conf\\spring\\MyBeansConfig.groovy'
}
... y de acuerdo condocs, 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)Siguiendolukelazarovic consejo, este enfoque funciona ya que Grails copia automáticamente (no compila) archivos geniales ensrc/java
a la ruta de clase; 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 bean personalizados engrails-app/conf/spring
(créditos paraideascultor ymark.esher)
//bean config files here
grails-app/conf/spring/MyBeansConfig.groovy
//## resources.groovy
//for eclipse/local testing
loadBeans('file:./grails-app/conf/spring/*BeansConfig.g,roovy')
//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 cree sus archivos de configuración de bean utilizando*BeansConfig.groovy
convención, ¡listo!
//bean config files here
grails-app/conf/spring/MyBeansConfig.groovy
Actualización 24/09/2015Encontró algunos problemas con la opción 3:
carga de archivos de recursos duplicadosrecursos de primavera no configurados correctamente paratest-app
Logramos solucionar el problema anterior de modo que cualquier archivo de recursos engrails-app/conf/spring
funciona igual al ejecutar Grails en eclipse, WAR, test-app, etc.
Primer paso: creamos una clase para tener más control sobre la ubicación y carga de archivos de recursos; Esto era necesario ya que algunos archivos se estaban cargando más de una vez debido a los beans de referencia cruzada. 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)
}
}
RemotoBeansConfig.groovy
sufijo; La generación WAR ahora recoge cualquier recurso engrails-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 desdedoWithSpring()
pasandoBeanBuilder
(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 engrails-app/conf/spring