2014-10-05 13 views
6

Tôi muốn sử dụng Dynamic Languages Support của Spring Framework.Sử dụng hỗ trợ ngôn ngữ động mùa xuân từ cấu hình Java

Trong XML tôi chỉ sử dụng không gian tên lang, nhưng tôi muốn sử dụng cấu hình Java (tức là @Configuration lớp học) chỉ.

Tôi có thể tưởng tượng rằng tôi có thể làm điều đó bằng cách khởi tạo tất cả địa ngục từ gói org.springframework.scripting.config, inc. tất cả các BeanPostProcessor s, Handler s, Parser s và FactoryBean s chúng tạo, nhưng tôi thực sự không muốn đến đó.

Có cách nào khác không? Nếu không có, cấu hình tối thiểu cần thiết để tạo ra một bean có thể nạp lại từ một kịch bản Groovy là gì?

Trả lời

5

Tại sao bạn không yêu cầu chúng tôi trực tiếp qua email? :-)

Tôi thấy rằng hỗ trợ XML Lang là ma thuật đáng kể. Có đủ nội dung dựa trên BeanDefinitionattributes của nó. Ngoài ra, có một số móc với ProxyFactoryCGLIB cho số lang:property.

Những gì tôi thấy cho JavaConfig là một số wrapper lớp Java cho ScriptEvaluatorRefreshableResourceScriptSource từ 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); 
     } 

    } 

} 

Trường hợp Calculator.groovy là:

x + y 

Tôi hiểu rằng nó không phải là quá linh hoạt như nó có giao diện và cấu hình từ định nghĩa XML, nhưng ít nhất nó sẽ giúp bạn thấy chúng ta đang ở đâu.

Vui lòng nêu vấn đề JIRA về vấn đề này và chúng tôi sẽ xem chúng tôi có thể làm gì ở đây. Một cái gì đó như @EnableScripting@ScriptSource(refreshDelay = 1000) trên phương pháp Resource@Bean.

Tôi nghĩ rằng hiện tại bạn chỉ có thể @Import một số đoạn mã XML có định nghĩa lang.

Chúc mừng, Artem

+0

Cám ơn câu trả lời của bạn, người đàn ông! Tôi không hỏi bằng email 1. Tôi nghĩ rằng đó là một câu hỏi hay để được công khai và có thể tìm thấy, 2. Bùng nổ, bạn chỉ nhận được 25 đại diện :) Không tệ lắm, tôi phải nói, tôi mong đợi tồi tệ hơn. Và có, '@ EnableScripting' là cách, tôi sẽ thêm một yêu cầu tính năng. – JBaruch

+0

https://jira.spring.io/browse/SPR-12300 Số may mắn :) – JBaruch

1

Tôi sẽ down the same path (công việc đang tiến), và đã quản lý để khởi kịch bản Groovy nạp thêm bằng cách thêm vào các định nghĩa bean khi Application Mùa xuân đang chuẩn bị. Trong ví dụ của tôi, tôi đang sử dụng spring-boot.

Nếu bạn thêm lớp AddBeanDefinitionsListener nghe sau đây và một bean ScriptFactoryPostProcessor, bạn có thể khởi tạo các kịch bản Groovy với rất ít công sức ...

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 
    } 

} 

Ứng dụng.groovy

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

} 

(Có thể đẹp hơn nếu được thực hiện với Spring 4.2's events?)

Các vấn đề liên quan