2011-10-07 18 views
5

Tengo una aplicación java basada en un resorte con algunos componentes útiles. Como parte del sistema, tengo una secuencia de comandos groovy, para procesar algunos informes. Me gustaría llamar a un componente de primavera de guión groovy. Cuando estoy escribiendo en Java, necesito utilizar @Autowired anotación dentro de la @Component, es decirComponente de Spring desde groovy

@Component 
class Reporter{ 
@Autowired 
SearchService searchService; 

void report(){ 
searchService.search(...); 
... 
} 
} 

¿Cómo puedo hacer lo mismo de maravilloso? Al principio, ¿cómo puedo definir @Component para todo el script? El siguiente código:

@Component class Holder{ 
    @Autowired 
    SearchService searchService; 

    def run(){ 
     searchService.search("test"); 
    } 
} 

new Holder().run() 

falla con NPE en searchService. Estoy ejecutando groovyscripts con GroovyClassloader instalados desde Java, si es que importa. ¡Muchas gracias de antemano!

+0

¿Cómo se crea el contexto de la aplicación de resorte? – gkamal

Respuesta

4

Si está utilizando @Component, debería crear contexto primavera como:

def ctx = new GenericApplicationContext() 
new ClassPathBeanDefinitionScanner(ctx).scan('') // scan root package for components 
ctx.refresh() 

o en el XML:

<context:component-scan base-package="org.example"/> 

El código debería funcionar si se crea el contexto que el anterior. Este es un ejemplo de Groovy Codehaus

import org.springframework.beans.factory.annotation.Autowired 
import org.springframework.stereotype.Component 

@Component class CalcImpl3 { 
    @Autowired private AdderImpl adder 
    def doAdd(x, y) { adder.add(x, y) } 
} 
+0

muchas gracias, es exactamente lo que necesitaba. Por cierto, me di cuenta de que lleva un tiempo crear y actualizar el contexto. Probablemente sería mejor pasar el contexto de primavera como un parámetro para el guión maravilloso, ¿no? – tmp120210

+0

definitivamente puede intentarlo, pero el contexto aún debe actualizarse (p.para '@ Autowired' para trabajar + otras cosas) – tolitius

+0

Gracias por esta respuesta, la más útil en la web en este momento: D sin embargo, después de anotar mi clase Groovy con Component e insertar las 3 líneas sobre el contexto en mi constructor, todavía no puedo Autocablear un servicio que tengo en mi proyecto de primavera. Me está diciendo que parece perder la configuración (liquibase config) pero tengo mi archivo application.yml agradable y pobre :( – Alex

1

tres posibilidades:

  1. Si el código Groovy puede ser pre-compilado y se incluye en la ruta de clase, entonces se crea y se inyecta como cualquier otro frijol sería durante <context:component-scan>. Parece que este no es el caso ya que está usando GroovyClassLoader.

  2. Use Spring Dynamic Language Support y use <lang:groovy> para crear su bean en lugar de usar GroovyClassLoader. Luego use <lang:property> para inyectar sus propiedades en lugar de usar @Autowired.

  3. Si aún necesita utilizar GroovyClassLoader, puede solicitar que se inyecte el frijol utilizando AutowiredAnnotationBeanPostProcessor.

Por ejemplo, si obj es una referencia al objeto creado por GroovyClassLoader:

AutowiredAnnotationBeanPostProcessor aabpp = 
    (AutowiredAnnotationBeanPostProcessor)applicationContext. 
     getBean(AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME); 

aabpp.processInjection(obj); 

Hay una cuarta posibilidad también, pero no estoy seguro si funciona con GroovyClassLoader, es use Load-time Weaving.

+0

Muchas gracias por la respuesta. Por lo que tengo entendido, tu respuesta es útil cuando necesitamos implementar un Bean in groovy, ¿no? Por ahora, solo quiero llamar al componente existente del guión maravilloso, así que no es útil para mí en este momento. Pero guardaré tu respuesta para referencia futura. – tmp120210