2014-10-05 53 views
6

我想使用Spring Framework的Dynamic Languages Support從Java配置中使用Spring動態語言支持

在XML中我只使用lang命名空間,但我想使用Java配置(即@Configuration類)只有

我可以想象,我可以通過初始化org.springframework.scripting.config package,inc。的所有地獄來做到這一點。所有的BeanPostProcessor s,Handler s,Parser s和FactoryBean s他們創造,但我真的不想去那裏。

還有其他的方法嗎?如果沒有,那麼從Groovy腳本創建可重載bean所需的最小配置是什麼?

回答

5

你爲什麼不直接通過電子郵件詢問我們? :-)

我看到XML Lang支持是非常神奇的。有足夠的東西是基於BeanDefinition和它的attributes。另外還有一些掛鉤ProxyFactoryCGLIBlang:property

我所看到的JavaConfig是一些Java類包裝的ScriptEvaluatorRefreshableResourceScriptSourceSpring Integration

@ContextConfiguration 
@RunWith(SpringJUnit4ClassRunner.class) 
public class RefreshableScriptJavaConfigTests { 

    @Autowired 
    private Calculator calculator; 

    @Test 
    public void testGroovyRefreshableCalculator() { 
     assertEquals(5, this.calculator.add(2, 3)); 
    } 

    @Configuration 
    public static class ContextConfiguration { 

     @Value("classpath:org/springframework/integration/scripting/config/jsr223/Calculator.groovy") 
     private Resource groovyScriptResource; 

     @Bean 
     public ScriptEvaluator groovyScriptEvaluator() { 
      return new GroovyScriptEvaluator(); 
     } 

     @Bean 
     public Calculator calculator() { 
      return new Calculator(new RefreshableResourceScriptSource(this.groovyScriptResource, 1000)); 
     } 

    } 

    public static class Calculator { 

     private final ScriptSource scriptSource; 

     @Autowired 
     private ScriptEvaluator scriptEvaluator; 

     public Calculator(ScriptSource scriptSource) { 
      this.scriptSource = scriptSource; 
     } 

     public int add(int x, int y) { 
      Map<String, Object> params = new HashMap<String, Object>(); 
      params.put("x", x); 
      params.put("y", y); 
      return (int) this.scriptEvaluator.evaluate(this.scriptSource, params); 
     } 

    } 

} 

Calculator.groovy是:

x + y 

我明白,這是不是這樣它具有靈活性,因爲它具有XML定義中的接口和配置,但至少可以幫助您瞭解我們的位置。

隨時就此事提出JIRA問題,我們將看到我們可以在這裏做什麼。類似@EnableScripting@ScriptSource(refreshDelay = 1000)Resource@Bean方法。

我認爲現在你可以只用@Import一些XML片段與lang的定義。

乾杯, 阿爾喬姆

+0

謝謝您的回答,男人! 我沒有通過電子郵件詢問原因1.我認爲這是一個很好的問答公開和可以找到的,2.熱潮,你剛剛得到了+25的代表:)這不是很糟糕,我不得不說,我預計會更糟糕。是的,'@ EnableScripting'就是這樣,我會添加一個功能請求。 – JBaruch 2014-10-06 10:38:38

+0

https://jira.spring.io/browse/SPR-12300幸運號碼:) – JBaruch 2014-10-06 11:18:25

1

我要去down the same path(工作正在進行中),並已成功通過準備的S​​pring應用程序時加入bean定義初始化增值的Groovy腳本。在我的示例中,我使用的是spring-boot

如果您添加以下AddBeanDefinitionsListener監聽器類和ScriptFactoryPostProcessor豆,你可以用很少的努力初始化Groovy腳本......

AddBeanDefinitionsListener.groovy

public class AddBeanDefinitionsListener 
     implements ApplicationListener<ApplicationPreparedEvent> { 

    Map<String, BeanDefinition> beanDefs 

    AddBeanDefinitionsListener(Map<String, BeanDefinition> beanDefs) { 
     this.beanDefs = beanDefs 
    } 

    @Override 
    void onApplicationEvent(ApplicationPreparedEvent event) { 
     def registry = (BeanDefinitionRegistry) event.applicationContext 
       .autowireCapableBeanFactory 
     beanDefs.each { String beanName, BeanDefinition beanDef -> 
      registry.registerBeanDefinition(beanName, beanDef) 
     } 
    } 

    /* Static Utility methods */ 

    static BeanDefinition groovyScriptFactory(String scriptLocation) { 
     def bd = BeanDefinitionBuilder.genericBeanDefinition(GroovyScriptFactory) 
       .addConstructorArgValue(scriptLocation) 
       .getBeanDefinition() 
     bd.setAttribute(ScriptFactoryPostProcessor.REFRESH_CHECK_DELAY_ATTRIBUTE, 1000) 
     bd 
    } 

} 

應用程序。常規

@SpringBootApplication 
public class Application { 

    public static void main(String[] args) { 
     SpringApplication app = new SpringApplication(Application) 
     app.addListeners(new AddBeanDefinitionsListener([ 
       'foobar0': groovyScriptFactory("file:/some/path/Foobar0Service.groovy"), 
       'foobar1': groovyScriptFactory("file:/some/path/Foobar1Service.groovy") 
     ])) 
     app.run(args) 
    } 

    @Bean 
    ScriptFactoryPostProcessor scriptFactory() { 
     new ScriptFactoryPostProcessor() 
    } 

} 

(如果與Spring 4.2's events實現的可能是更好?)