복붙노트

[SPRING] grails app에 사용자 정의 groovy 파일에서 spring beans로드

SPRING

grails app에 사용자 정의 groovy 파일에서 spring beans로드

Grails 2.3.7에서 커스텀 Groovy 파일로부터 스프링 빈을로드하려고합니다. 나는이 질문이 이전에 요청되었지만 몇 시간의 검색 후에도 클래스 경로에서로드되는 일관된 접근 방식을 찾을 수 없다는 것을 알고 있습니다.

//## grails-app/conf/spring/MyBeansConfig.groovy 
beans {
   testsvc(TestService){
      msg = 'hello'
   }
}

위의 노트에서 bean {}이 아닌 beans {}를 사용하고 있습니다. 분명히 차이가 있습니다.

resources.groovy

이 작품은 ...

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

... 및 문서에 따르면, 이것 역시해야하지만, 그렇지 않습니다 :

importBeans("classpath:*MyBeansConfig.groovy")

(Grails 2.3.7 작업)

lukelazarovic advice에 따르면 Grails는 src / java에있는 Groovy 파일을 클래스 패스에 자동으로 복사 (컴파일하지 않음)하므로이 방법이 유용합니다. 일식과 전쟁 배포에서 잘 작동합니다.

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

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

이 방법은 grails-app / conf / spring (ideascultor 및 mark.esher에 대한 크레디트)에서 사용자 정의 bean 구성 파일을 허용합니다.

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

맞춤 플러그인을 사용하는 경우이 방법이 이상적입니다. 보일러 플레이트 구성이 플러그인으로 리팩터링 됨 :

플러그인 구성

   //## 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 config files here
grails-app/conf/spring/MyBeansConfig.groovy

옵션 3과 관련된 몇 가지 문제점을 발견했습니다.

이클립스, WAR, test-app 등에서 Grails를 실행할 때 grails-app / conf / spring의 모든 리소스 파일이 동일하게 작동하도록 위의 문제를 해결했습니다.

첫 번째 단계 : 리소스 파일의 위치를 ​​지정하고로드하는 것을보다 효율적으로 제어 할 수있는 클래스를 만들었습니다. 상호 참조 된 빈 (bean)으로 인해 일부 파일이 두 번 이상로드 될 때 필요했습니다. 이 기능을 캡슐화하기 위해 플러그인을 사용하고 있으므로이 클래스는 해당 플러그인에 있습니다.

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의 모든 리소스를 선택합니다.

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 (대리자)를 인수로 전달합니다 (매우 중요 함).

def doWithSpring = {       
   CustomResourceLoader.loadSpringBeans(delegate)
}

즉, grails-app / conf / spring에서 사용자 정의 리소스 파일을 만드는 것을 제외하고는 플러그인 사용자에 대한 요구 사항이 없습니다.

해결법

  1. ==============================

    1.며칠 전 grails-app / conf에 추가 한 그루비 한 설정 파일로 비슷한 문제가 발생했습니다. 이 작업은 다른 리소스 (클래스 패스에서 복사 및 사용할 수 있음)와 작동하지만 그루비 파일의 문제는 단순히 컴파일 된 것이고 클래스 파일이 포함 된 것입니다. 즉, 그루비 파일 자체가 아닙니다.

    며칠 전 grails-app / conf에 추가 한 그루비 한 설정 파일로 비슷한 문제가 발생했습니다. 이 작업은 다른 리소스 (클래스 패스에서 복사 및 사용할 수 있음)와 작동하지만 그루비 파일의 문제는 단순히 컴파일 된 것이고 클래스 파일이 포함 된 것입니다. 즉, 그루비 파일 자체가 아닙니다.

    이것이 어떻게 수행되어야하는지에 대한 좋은 문서를 찾지 못했고 마침내 web-app / WEB-INF / classes에 추가했습니다. Groovy 파일은 여기에 복사되고 (컴파일되지는 않음) 클래스 패스에서 사용할 수 있습니다.

  2. ==============================

    2.Grails 2.1.2에서 사용자 정의 XML 파일과 동일한 문제가있었습니다.

    Grails 2.1.2에서 사용자 정의 XML 파일과 동일한 문제가있었습니다.

    프로덕션 환경 AFAIR에서는 grails-app / conf / spring에 XML 리소스가 포함되지 않았습니다.

    개발 및 프로덕션 환경에서 모두 작동하도록하기 위해 마침내 src / java에 자원을 넣었습니다. Groovy 파일을 src / groovy에 넣음으로써 같은 결과를 얻을 수 있다고 생각합니다.

  3. ==============================

    3.우리는 다음과 같은 방식으로 다른 groovy / xml 파일에서 콩을 가져올 수 있습니다. resources.groovy에서 다음을 사용하십시오 -

    우리는 다음과 같은 방식으로 다른 groovy / xml 파일에서 콩을 가져올 수 있습니다. resources.groovy에서 다음을 사용하십시오 -

    importBeans '파일 : camel-beans.groovy' 또는 importBeans ( 'classpath : /camel-config.xml')

    resources.groovy와 함께 camel-beans.groovy를 배치하고 첫 번째 경우에는 패키지를 "패키지 스프링"으로 제공하고 그렇지 않으면 웹 앱 클래스 경로에 배치하고 두 번째 방법으로이를 수행하십시오.

  4. ==============================

    4.resources.groovy가 다음 경로에있는 경우

    resources.groovy가 다음 경로에있는 경우

    grails-app/conf/spring/resources.groovy
    

    너의 낙타 - 콩. 루비는 다음 경로에있다.

    grails-app/conf/spring/camel-beans.groovy
    

    resources.groovy에 다음 줄을 추가하여 resources.groovy 파일에서 camel-beans.groovy를 참조 할 수 있습니다.

    importBeans('file:**/camel-beans.groovy')
    
  5. from https://stackoverflow.com/questions/24028410/load-spring-beans-from-custom-groovy-files-in-grails-app by cc-by-sa and MIT license