开发者

Calling Spring component from groovy

I have a spring-based java application with some useful components. As a part of the system I have a groovy script, to process some reports. I would like to call a spring component from groovy script. When I'm writing in Java, I need to use @Autowired annotation inside the @Component, i.e.

@Component
class Reporter{
@Autowired
SearchService searchService;

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

How can I do the same from groovy? At first, how I can define @Component for whole script? The following code:

@Component class Holder{
    @Autowired
    SearchService searchService;

    def run(){
        searchService开发者_运维问答.search("test");
    }
}

new Holder().run()

fails with NPE on searchService. I'm running groovyscripts with GroovyClassloader instatiaded from Java, if it matters. Thanks a lot in advance!


If you are using @Component, you should create Spring context as:

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

or in the XML:

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

Your code should work if the context is created as above. Here is an example from 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) }
}


Three possibilities:

  1. If your Groovy code can be pre-compiled and included in the classpath then it will be created and injected as any other bean would be during <context:component-scan>. It sounds like this may not be the case since you are using GroovyClassLoader.

  2. Use Spring Dynamic Language Support and use <lang:groovy> to create your bean instead of using GroovyClassLoader. Then use <lang:property> to inject your properties instead of using @Autowired.

  3. If you still need to use GroovyClassLoader then you can ask the bean to be injected by using AutowiredAnnotationBeanPostProcessor.

For example, if obj is a reference to the object created by GroovyClassLoader:

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

aabpp.processInjection(obj);

There is a fourth possibility too, but I am not sure if it works with GroovyClassLoader, that is to use Load-time Weaving.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜