使用Groovy配置中的Spring动态语言支持

时间:2015-08-25 14:10:15

标签: java spring groovy spring-boot spring-annotations

我想使用Spring Framework的Dynamic Languages Support,从Groovy脚本创建一个可重新加载的 bean(在运行时!)。我想避免xml配置,并在Spring Boot应用程序上下文中使用注释(或类似)。

这是对question that's already been asked的扩展,我希望通过BeanPostProcessorsHandlersParsers,{{1}来解决问题。 }。

我已经快速浏览了ScriptFactoryPostProcessor的javadoc,并提出了一些工作示例。我想知道whatever it takes为什么不起作用?

beans.xml - 有效! (但我想在 Application.groovy 而不是Application.groovy (v2)中定义bean ...)

xml

Application.groovy(v1) - 有效! (但这是一个非常丑陋的解决方法)

<bean class="org.springframework.scripting.support.ScriptFactoryPostProcessor">
    <property name="defaultRefreshCheckDelay" value="1000" />
</bean>

<bean id="foobar0" class="org.springframework.scripting.groovy.GroovyScriptFactory">
    <constructor-arg value="file:/C:/someDir/src/main/static/FoobarService.groovy"/>
</bean>

Application.groovy(v2) - 不起作用 - 为什么不呢?

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Application)
        // Add GroovyScriptFactory after Application is prepared...
        app.addListeners(new ApplicationListener<ApplicationPreparedEvent>() {
            void onApplicationEvent(ApplicationPreparedEvent event) {
                def registry = (BeanDefinitionRegistry) event.applicationContext.autowireCapableBeanFactory
                def bd = BeanDefinitionBuilder.genericBeanDefinition(GroovyScriptFactory)
                        .addConstructorArgValue("file:/C:/someDir/src/main/static/FoobarService.groovy")
                        .getBeanDefinition()
                bd.setAttribute(ScriptFactoryPostProcessor.REFRESH_CHECK_DELAY_ATTRIBUTE, 1000)
                registry.registerBeanDefinition('foobar0', bd)
            }
        })
        app.run(args)
    }
    @Bean
    ScriptFactoryPostProcessor scriptFactory() {
        new ScriptFactoryPostProcessor()
    }
}

看起来它与如何/何时在ApplicationContext的生命周期中初始化bean定义有关。我尝试使用@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application, args) } @Bean ScriptFactoryPostProcessor scriptFactory() { new ScriptFactoryPostProcessor() } @Bean GroovyScriptFactory foobar0() { new GroovyScriptFactory("file:/C:/someDir/src/main/static/FoobarService.groovy") } } @Order来控制bean的排序 - 无济于事。值得一提的是,我现在重复了以下日志 - 看起来@DependsOn不断地用#&#34; null&#34;覆盖bean。 bean定义(为什么?)。

ScriptFactoryPostProcessor

相关:

  • SPR-10253 - 刷新带注释的Groovy控制器会导致ClassCastException
  • SPR-10689 - 版本2.5及更高版本中的标记不适用于可刷新的Spring MVC端点
  • SPR-12300 - 在@Configuration类中添加对动态语言可刷新bean的支持

2 个答案:

答案 0 :(得分:2)

为什么不只是

@Bean
ScriptFactoryPostProcessor scriptFactory() {
   ScriptFactoryPostProcessor sfpp = new ScriptFactoryPostProcessor()
   sfpp.setDefaultRefreshCheckDelay(1000)
   return sfpp
}

答案 1 :(得分:0)

更简单的替代方案:

  • 将FooBarService放在类路径上并使用@Component
  • 进行注释

  • 使用mybeans.xml中的lang命名空间

-

<lang:groovy id="foobarService"
    script-source="file:src/main/static/FoobarService.groovy" />

<强> Application.groovy

@SpringBootApplication
@ImportResource("classpath:mybeans.xml")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application, args)
    }
}