2011-10-07 90 views
5

我有一個基於spring的java應用程序,它帶有一些有用的組件。作爲系統的一部分,我有一個groovy腳本來處理一些報告。我想從groovy腳本中調用一個spring組件。 當我在Java中正在寫,我需要使用@Component@Autowired註解,即從groovy調用Spring組件

@Component 
class Reporter{ 
@Autowired 
SearchService searchService; 

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

我如何可以做同樣的常規? 首先,我如何爲整個腳本定義@Component? 以下代碼:

@Component class Holder{ 
    @Autowired 
    SearchService searchService; 

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

new Holder().run() 

失敗上searchService NPE。 我正在運行groovyscripts與從Java創建,如果它很重要。 非常感謝!

+0

如何創建spring應用程序上下文? – gkamal

回答

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"/> 

您的代碼應該工作。這裏是

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) } 
} 
+0

非常感謝,這正是我所需要的。順便說一句,我注意到,它需要一些時間來創建和刷新上下文。或許最好將spring context作爲參數傳遞給groovy腳本,不是嗎? – tmp120210

+0

你肯定可以嘗試,但仍需要刷新上下文(例如,爲''Autowired'工作+其他事情) – tolitius

+0

感謝您的答案,此時最有用的網絡:D然而,在註釋我的Groovy類與組件,並在我的構造函數插入關於上下文的3行,我仍然不能在我的Spring項目中使用Autowire服務。它告訴我,它似乎錯過配置(liquibase配置),但我有我的application.yml文件很好,並精益:( – Alex

1

三種可能性從Groovy Codehaus一個例子:

  1. 如果你的Groovy代碼可以被預編譯和包含在類路徑那麼它將被創建並注入其它bean會在<context:component-scan>期間。這聽起來可能不是這樣,因爲您正在使用GroovyClassLoader

  2. 使用彈簧Dynamic Language Support並使用<lang:groovy>創建您的bean而不是使用GroovyClassLoader。然後使用<lang:property>注入您的屬性,而不是使用@Autowired

  3. 如果您仍然需要使用GroovyClassLoader那麼您可以通過使用AutowiredAnnotationBeanPostProcessor來要求bean被注入。

例如,如果obj是由GroovyClassLoader創建的對象的引用:

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

aabpp.processInjection(obj); 

還有第四種可能性太多,但我不知道,如果它的工作原理與GroovyClassLoader,那就是使用Load-time Weaving

+0

非常感謝答覆。據我瞭解,您的答案是有用的,當我們需要實現現在,我只是想從groovy腳本中調用現有的組件,所以它現在對我沒有用處,但我會保存你的答案供以後參考。 – tmp120210