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

问题描述 投票:9回答:2

我想使用Spring框架的Dynamic Languages Support,创造增值的豆(在运行时!)从Groovy脚本。我想避免xml配置,以及一个Spring Boot应用程序上下文内使用的标注(或类似)。

这是一个扩展到question that's already been asked,扩展是,我确实希望得到我的手脏BeanPostProcessorsHandlersParserswhatever it takes

我有一个快速浏览一下的Javadoc ScriptFactoryPostProcessor,并纷纷拿出合作的例子。我想知道为什么Application.groovy (v2)不起作用?


beans.xml中 - 作品! (但我要定义Application.groovy代替xml豆...)

<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(V1) - 的作品! (但是是一个非常丑陋的解决方法)

@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()
    }
}

Application.groovy(V2) - 不工作 - 为什么不呢?

@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")
    }
}

它看起来像它的东西做如何/当豆定义,一个ApplicationContext的生命周期被初始化。我已经使用@Order尝试和@DependsOn控制豆订货 - 无济于事。值得一提的,我现在越来越重复以下日志 - (为什么?),它看起来像ScriptFactoryPostProcessor不断改写着有“空” bean定义这个bean。

2015-08-27 12:04:11.312  INFO 5780 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     :
Overriding bean definition for bean 'scriptFactory.foobar0': replacing [Generic bean: class [null];
scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; p
rimary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=n
ull] with [Generic bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=0; depen
dencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; i
nitMethodName=null; destroyMethodName=null]

有关:

  • SPR-10253 - 清爽注释Groovy的控制器引起ClassCastException异常
  • SPR-10689 - 标签在2.5及更高版本不适用刷新Spring MVC的端点工作
  • SPR-12300 - 增加支持动态语言刷新豆@Configuration类
java spring groovy spring-boot spring-annotations
2个回答
2
投票

为什么不只是

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

0
投票

更简单的方法:

  • 把FooBarService在类路径上,并用@Component来注解它

要么

  • 使用mybeans.xml郎命名空间

-

<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)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.