2015-08-25 19 views
7

Tôi muốn sử dụng Dynamic Languages Support của Spring Framework, để tạo ra một nạp đậu (khi chạy!) từ một kịch bản Groovy. Tôi muốn tránh cấu hình xml và sử dụng chú thích (hoặc tương tự) trong ngữ cảnh ứng dụng Spring Boot.Sử dụng mùa xuân động Ngôn ngữ hỗ trợ từ Groovy Cấu hình

Đây là một phần mở rộng cho một question that's already been asked, phần mở rộng được rằng tôi muốn có được bàn tay của tôi bẩn với BeanPostProcessors, Handlers, Parsers, whatever it takes.

Tôi đã xem nhanh javadoc cho ScriptFactoryPostProcessor và đã đưa ra các ví dụ hoạt động. Tôi muốn biết tại sao Application.groovy (v2) không hoạt động?


beans.xml - công trình! (Nhưng tôi muốn xác định đậu ở Application.groovy thay vì 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) - công trình! (Nhưng là một cách giải quyết rất xấu xí)

@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) - không hoạt động - tại sao không?

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

Dường như nó là cái gì để làm với cách/khi các định nghĩa đậu được khởi tạo trong vòng đời của một ApplicationContext. Tôi đã thử sử dụng @Order@DependsOn để kiểm soát thứ tự bean - không có kết quả. Đáng nói đến, bây giờ tôi nhận được các bản ghi sau lặp đi lặp lại - trông giống như ScriptFactoryPostProcessor liên tục ghi đè lên bean với một định nghĩa bean "null" (tại sao?).

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] 

liên quan:

  • SPR-10253 - Refreshing điều khiển Groovy chú thích gây ClassCastException
  • SPR-10689 - thẻ trong phiên bản 2.5 và cao hơn không làm việc cho làm mới Spring MVC điểm cuối
  • SPR-12300 - Thêm hỗ trợ cho các ngôn ngữ động đậu làm mới trong các lớp @Configuration
+0

[Các câu hỏi mà bạn có liên quan đến] (http: // stackoverflow. com/q/26208020/880772) chứa một ví dụ sử dụng cấu hình Java. Điều đó có phù hợp với bạn không? Tại sao không sử dụng 'RefreshableResourceScriptSource'? – approxiblue

+0

@approxiblue - đó là một ví dụ tốt, nhưng nó đòi hỏi một lớp Bean wrapper (tức là 'Calculator') để tự động gọi ra' ScriptEvaluator' bên dưới. Điều gì sẽ xảy ra khi tôi muốn thêm một chức năng mới "trừ"? Tôi có phải thêm phương thức mới vào 'Máy tính' và biên dịch lại lớp không? Không phải rất năng động. Lý tưởng nhất mà tôi muốn là một kịch bản/lớp Groovy, những thay đổi có thể được phát hiện và cập nhật vào thời gian chạy của Spring, bản thân nó là một bean Spring (và tất cả các phép thuật tự động đi kèm với nó). Hãy nghĩ về '@ RestController' mà bạn có thể cập nhật và thêm vào tự động khi chạy. –

+0

Dường như nó tạo ra các hạt có thể làm mới từ các tập lệnh Groovy: https://gist.github.com/thomasdarimont/f7f2ef6f4900b9f89d58 – cybersoft

Trả lời

0

đơn giản lựa chọn:

  • đặt FooBarService trên classpath và chú thích nó với @Component

hoặc

  • sử dụng namespace lang trong 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) 
    } 
} 
+2

Cảm ơn các giải pháp thay thế @ slim-l, nhưng không may cả hai giải pháp của bạn không giải quyết được câu hỏi của tôi t ** có thể tải lại **, trừ khi tôi bị nhầm lẫn). Lựa chọn thay thế đầu tiên của bạn không sử dụng [DLS] (http://docs.spring.io/spring/docs/current/spring-framework-reference/html/dynamic-language.html). Phương án thứ hai của bạn thiếu thuộc tính 'refresh-check-delay =" 1000 "và cũng đang sử dụng' xml' mà tôi muốn tránh. –

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