从groovy调用Spring组件

时间:2011-10-07 15:19:00

标签: java spring groovy autowired

我有一个基于Spring的java应用程序,其中包含一些有用的组件。作为系统的一部分,我有一个groovy脚本,来处理一些报告。我想从groovy脚本中调用spring组件。 当我用Java编写时,我需要在@Autowired内使用@Component注释,即

@Component
class Reporter{
@Autowired
SearchService searchService;

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

我如何从groovy做同样的事情? 首先,我如何为整个脚本定义@Component? 以下代码:

@Component class Holder{
    @Autowired
    SearchService searchService;

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

new Holder().run()

searchService上的NPE失败。 如果重要的话,我正在使用Java GroovyClassloader运行groovyscripts。 非常感谢提前!

2 个答案:

答案 0 :(得分:4)

如果您使用@Component,则应将Spring上下文创建为:

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

或在XML中:

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

如果上面创建了上下文,您的代码应该有效。以下是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) }
}

答案 1 :(得分:1)

三种可能性:

  1. 如果您的Groovy代码可以预编译并包含在类路径中,那么它将在<context:component-scan>期间创建并注入任何其他bean。听起来可能并非如此,因为您使用的是GroovyClassLoader

  2. 使用Spring Dynamic Language Support并使用<lang:groovy>创建bean,而不是使用GroovyClassLoader。然后使用<lang:property>注入您的属性,而不是使用@Autowired

  3. 如果您仍然需要使用GroovyClassLoader,那么您可以使用AutowiredAnnotationBeanPostProcessor来请求注入bean。

  4. 例如,如果obj是对GroovyClassLoader创建的对象的引用:

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

    还有第四种可能性,但我不确定它是否适用于GroovyClassLoader,即使用Load-time Weaving