java - starter - spring boot wikipedia
Uso de Spring Dynamic Languages Support desde Groovy Configuration (1)
Alternativas más simples:
- poner FooBarService en classpath y anotarlo con @Component
o
- usa el espacio de nombres lang en 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)
}
}
Me gustaría utilizar el soporte de idiomas dinámicos de Spring Framework, para crear un bean recargable ( en tiempo de ejecución ) de un script de Groovy. Quiero evitar la configuración xml
y usar anotaciones (o similares) dentro de un contexto de Spring Boot
Application.
Esta es una extensión de una pregunta que ya se hizo , la extensión es que BeanPostProcessors
ensuciarme las manos con BeanPostProcessors
, Handlers
, Parsers
, whatever it takes
.
He echado un vistazo rápido al javadoc para ScriptFactoryPostProcessor , y he encontrado ejemplos de trabajo. Quiero saber por qué Application.groovy (v2)
no funciona?
beans.xml - ¡funciona! (pero quiero definir los beans en Application.groovy en lugar de 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) - funciona! (pero es una solución muy fea)
@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) - no funciona - ¿por qué no?
@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")
}
}
Parece que tiene que ver con cómo / cuándo las definiciones de beans se inicializan en el ciclo de vida de un ApplicationContext. Intenté usar @Order
y @DependsOn
para controlar el pedido de frijoles, pero fue en vano. Vale la pena mencionar que ahora recibo el siguiente registro repetido, que parece que ScriptFactoryPostProcessor
sobrescribe continuamente el bean con una definición de bean "nula" (¿por qué?).
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]
Relacionado: