从 grails 应用程序中的自定义 groovy 文件加载 spring bean [英] Load spring beans from custom groovy files in grails app

查看:21
本文介绍了从 grails 应用程序中的自定义 groovy 文件加载 spring bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试从 Grails 2.3.7. 中的自定义 groovy 文件加载 spring bean.我知道之前有人问过这个问题,但是经过数小时的搜索,我找不到一致的方法从类路径加载.

Trying to load spring beans from custom groovy file in Grails 2.3.7. I know this question has been asked before, but after hours of searching, I'm unable to find a consistent approach that loads from the classpath.

  • resources.groovy模块化为多个自定义资源文件
  • 将自定义资源文件放在标准位置:grails-app/conf/spring
  • 使用插件来创造奇迹;最小化开销
  • Modularize resources.groovy into multiple custom resource files
  • Put custom resource files in standard location: grails-app/conf/spring
  • Use plugin to do the magic; minimize overhead
//## grails-app/conf/spring/MyBeansConfig.groovy 
beans {
   testsvc(TestService){
      msg = 'hello'
   }
}

注意上面,我使用的是 beans {},而不是 beans = {}显然它有所作为:

Note above, I'm using beans {}, not beans = {}, apparently it makes a difference:

resources.groovy

这有效...

beans = {
  loadBeans 'file:C:\ProjTest1grails-app\conf\spring\MyBeansConfig.groovy'
}

...并且根据 docs,这也应该,但没有:

...and according to docs, this should too, but doesn't:

importBeans("classpath:*MyBeansConfig.groovy")

更新 - 工作选项

(适用于 Grails 2.3.7)

遵循 lukelazarovic 建议,这种方法有效,因为 Grails 会自动复制(而不是编译)src/中的 groovy 文件java 到类路径;在 Eclipse 和战争部署中工作正常:

Following lukelazarovic advice, this approach works since Grails automatically copies (not compiles) groovy files in src/java to the classpath; works fine in eclipse and with war deployment:

//bean config files here
src/java/MyBeansConfig.groovy
src/java/FooBeansConfig.groovy

//resources.groovy
loadBeans('classpath*:*BeansConfig.groovy')

选项 2: (grails-app/conf/spring)

这种方法允许在 grails-app/conf/spring 中自定义 bean 配置文件(归功于 ideascultormark.esher)

Options 2: (grails-app/conf/spring)

This approach allows for custom bean config files in grails-app/conf/spring (credits to ideascultor and 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")
         }
      }
   }

选项 3:(自定义插件)

如果您使用自定义插件,这种方法是理想的;样板配置被重构到插件中:

Options 3: (Custom Plugin)

If you're using custom plugins, this approach is ideal; boiler plate config gets refactored into the plugin:

插件配置

   //## 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') 
   }

Grails 应用

无需配置!...只需使用 *BeansConfig.groovy 约定创建您的 bean 配置文件,一切顺利!

No config!...just create your bean config files using the *BeansConfig.groovy convention, good to go!

//bean config files here
grails-app/conf/spring/MyBeansConfig.groovy

2015/9/24 更新

发现选项 3 存在一些问题:

Update 9/24/2015

Found some issues with option 3:

  • 加载重复的资源文件
  • 没有为 test-app 正确配置 spring 资源
  • loading of duplicate resource files
  • spring resources not configured correctly for test-app

我们设法解决了上述问题,使得 grails-app/conf/spring 中的任何资源文件在 eclipse、WAR、test-app 等中执行 Grails 时都可以正常工作.

We managed to fix the above issue such that any resource files in grails-app/conf/spring work the same when executing Grails in eclipse, WAR, test-app, etc.

第一步:我们创建了一个类来更好地控制定位和加载资源文件;这是必要的,因为由于交叉引用 bean,一些文件被加载不止一次.我们使用一个插件来封装这个功能,所以这个类存在于那个插件中:

First step: we created a class to have more control over locating and loading resource files; this was necessary as some files were being loaded more than once due to cross-referenced beans. We're using a plugin to encapsulate this functionality, so this class lives in that plugin:

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)
   }
}

去除了BeansConfig.groovy后缀;WAR 生成现在选择 grails-app/conf/spring

Removed BeansConfig.groovy suffix; WAR generation now picks up any resources in 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")
         }
      }
   }
}

在插件定义文件中,从doWithSpring()调用加载器,传递BeanBuilder(委托)作为参数(非常重要):

In the plugin definition file, call the loader from doWithSpring(), passing BeanBuilder (the delegate) as the argument (very important):

def doWithSpring = {       
   CustomResourceLoader.loadSpringBeans(delegate)
}

就是这样,除了在grails-app/conf/spring

推荐答案

就在几天前,我遇到了类似的问题,我将一个 groovy 配置文件添加到了 grails-app/conf 中.虽然这适用于其他资源(它们被复制并在类路径上可用),但 groovy 文件的问题只是它被编译并包含了类文件,即不是 groovy 文件本身.

I had a similar problem just a few days ago, with a groovy configuration file that I added into grails-app/conf. While this works with other resources (they are copied and available on the classpath), the problem with the groovy file was simply that it was compiled and the class file was included, i.e. not the groovy file itself.

我没有找到任何关于如何应该完成的好的文档,最后只是将它添加到web-app/WEB-INF/classes.放置在这里的 Groovy 文件将被复制(未编译)并在类路径中可用.

I didn't find any good documentation on how this should be done and finally just added it to web-app/WEB-INF/classes. Groovy files placed here will be copied (not compiled) and available on the classpath.

这篇关于从 grails 应用程序中的自定义 groovy 文件加载 spring bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆