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:
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 usingGroovyClassLoader
.Use Spring Dynamic Language Support and use
<lang:groovy>
to create your bean instead of usingGroovyClassLoader
. Then use<lang:property>
to inject your properties instead of using@Autowired
.If you still need to use
GroovyClassLoader
then you can ask the bean to be injected by usingAutowiredAnnotationBeanPostProcessor
.
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.
精彩评论