Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Spring Dynamic Languages Support from Java Configuration

I'd like to use Dynamic Languages Support of Spring Framework.

In XML I'd just use the lang namespace, but I'd like to use Java configuration (i.e. @Configuration classes) only.

I can imagine that I can do it by initializing all the hell from org.springframework.scripting.config package, inc. all the BeanPostProcessors, Handlers, Parsers and FactoryBeans they create, but I really don't want to go there.

Is there some other way? If there's none, what will be the minimal configuration needed to create a reloadable bean out of a Groovy script?

like image 877
JBaruch Avatar asked Oct 05 '14 22:10

JBaruch


1 Answers

Why don't you ask us directly by email? :-)

I see that XML Lang support is relly magic. There is enough stuff which is based on BeanDefinition and its attributes. In additional there are some hooks with ProxyFactory and CGLIB for the lang:property.

What I see for the JavaConfig is some Java class wrapper for the ScriptEvaluator and RefreshableResourceScriptSource from Spring 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);
        }

    }

}

Where the Calculator.groovy is:

x + y

I understand that it isn't so flexible as it looks with interfaces and configuration from XML definition, but at least it will help you to see where we are.

Feel free to raise a JIRA issue on the matter and we'll see what we can do here. Something like @EnableScripting and @ScriptSource(refreshDelay = 1000) on the Resource @Bean method.

I think for now you can just @Import some XML snippets with lang definitions.

Cheers, Artem

like image 59
Artem Bilan Avatar answered Dec 01 '22 17:12

Artem Bilan