Вызывающая пружина компонент из шпунта - PullRequest
5 голосов
/ 07 октября 2011

У меня есть Java-приложение на основе Spring с некоторыми полезными компонентами. Как часть системы, у меня есть отличный скрипт для обработки некоторых отчетов. Я бы хотел назвать пружинный компонент из groovy script. Когда я пишу на 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()

терпит неудачу с NPE на searchService. Я запускаю groovyscript с GroovyClassloader, инсталлированным из Java, если это важно Заранее большое спасибо!

Ответы [ 2 ]

4 голосов
/ 07 октября 2011

Если вы используете @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 голос
/ 08 октября 2011

Три возможности:

  1. Если ваш код Groovy можно предварительно скомпилировать и включить в путь к классам, он будет создан и внедрен так же, как и любой другой bean-компонент во время <context:component-scan>. Похоже, что это не может иметь место, так как вы используете GroovyClassLoader.

  2. Используйте Spring Dynamic Language Support и используйте <lang:groovy> для создания вашего компонента вместо использования GroovyClassLoader. Затем используйте <lang:property> для ввода ваших свойств вместо @Autowired.

  3. Если вам все еще нужно использовать GroovyClassLoader, вы можете попросить боб быть введенным с помощью AutowiredAnnotationBeanPostProcessor.

Например, если obj является ссылкой на объект, созданный GroovyClassLoader:

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

aabpp.processInjection(obj);

Существует и четвертая возможность, но я не уверен, что она работает с GroovyClassLoader, то есть для использования Плетение времени загрузки .

...