从groovy调用Spring组件

发布于 2024-12-08 23:31:05 字数 697 浏览 0 评论 0原文

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

@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。 预先非常感谢!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

郁金香雨 2024-12-15 23:31:05

如果您使用 @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) }
}

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) }
}
中二柚 2024-12-15 23:31:05

三种可能性:

  1. 如果您的 Groovy 代码可以预编译并包含在类路径中,那么它将像 期间的任何其他 bean 一样被创建和注入。听起来情况可能并非如此,因为您使用的是 GroovyClassLoader

  2. 使用 Spring 动态语言支持并使用来创建bean,而不是使用GroovyClassLoader。然后使用 注入属性,而不是使用 @Autowired

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

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

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

aabpp.processInjection(obj);

还有第四种可能性,但我不确定它是否适用于 GroovyClassLoader< /code>,即使用 加载时编织

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文