2015-06-26 16 views
6

Hãy nói rằng tôi có lớp học này:Sử dụng một hàm Java8 Lambda bên trong XML mùa xuân

public class FooToBarTransformer { 
    public Bar transform(Foo foo) { 
     // do some cool stuff 
    } 
} 

Và tôi muốn tiêu thụ nó như một Function trong một số lớp khác:

public class Thing { 
    public Thing(Function<Foo, Bar> f) { 
     this.converter = f; 
    } 
} 

Bây giờ, nếu tôi 'm instantiating một Thing qua Java, tôi muốn làm điều đó với Java8 Lambdas như thế này:

FooToBarTransformer transformer = new FooToBarTransformer(); 
new Thing((foo) -> transformer.transform(foo)); 
// or new Thing(transformer::transform); 

Vấn đề của tôi là tôi cần tạo Thing mặc dù mùa xuân.

<bean id="fooToBarTransformer" class="com.mypackage.FooToBarTransformer"/> 
<bean id="theThing" class="com.mypackage.Thing"> 
    <constructor-arg index="0" ????????? /> 
</bean> 

Giờ đây, có một vài cách giải quyết có thể, tôi đã xem xét để làm điều này dễ dàng hơn:

  1. nếu FooToBarTransformer thực hiện Function, sau đó nó sẽ chỉ là một đơn giản ref="fooToBarTransformer"
  2. tôi có thể tạo ra một giao diện khác nhau mà FooToBarTransformer thực hiện và thay đổi Thing để xem phiên bản giao diện đó thay vì Function. Đối với mục đích của câu hỏi này, không phải trong số đó là những lựa chọn.

Dựa trên một số cách khác tôi đã nhìn thấy làm hành quyết trong xml mùa xuân, tôi đã cố gắng value="#{(foo) -> fooToBarTransformer.transform(foo)}"value="#{fooToBarTransformer::transform}" nhưng mùa xuân nghẹn ngào về vấn đề này.

Lựa chọn tốt nhất mà tôi đã đưa ra cho đến nay là để cung cấp một chức năng dịch trong mã:

public Function<Foo, Bar> toFunction() { 
    return transformer::transform; 
} 

và tham khảo nó trong mùa xuân với value="#{fooToBarTransformer.toFunction()}", nhưng điều này có vẻ khá hokey.

Có cách nào tốt hơn để thực hiện việc này không?

+1

Lưu ý phụ: 'Điều mới (biến áp :: biến đổi);' – assylias

+1

http://stackoverflow.com/questions/30651157/how-to-declare-a-java-8-method-reference-in-a- spring-xml-file –

+2

Về cơ bản, bạn không thể. Không có ký hiệu để hỗ trợ nó vào lúc này. –

Trả lời

2

Tôi nghĩ điều bạn cần làm là chuyển sang Java Config (http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-java) Trong thời gian chờ đợi, nếu bạn không thể chuyển đổi, bạn vẫn có thể tắt bằng cách kết hợp các phương pháp.Trong bạn XML file cấu hình add:

<bean class="com.myapp.config.FooBarConfiguration"/> 

Sau đó, bạn tạo lớp com.myapp.config.FooBarConfiguration như thế này:

@Configuration 
public class FooBarConfiguration { 
    @Bean 
    public FooToBarTransformer fooTransformer() { 
     return new FooToBarTransformer(); 
    } 

    @Bean 
    public Thing theThing(FooToBarTransformer fooTransformer) { 
     return new Thing(fooTransformer::transform); 
    } 
} 

Chỉ cần chắc chắn rằng ConfigurationClassPostProcessor là một đăng ký sau xử lý trong bối cảnh mùa xuân của bạn bằng cách có :

<context:annotation-config>

Hoặc

<context:component-scan>

Hoặc bằng cách thủ công thêm bộ xử lý bài như một bean:

<bean class="org.springframework.context.annotation.ConfigurationClassPostProcessor"/>

này nên làm việc từ mùa xuân 3.0 trở lên theo với http://docs.spring.io/spring/docs/current/javadoc-api/index.html?org/springframework/context/annotation/ConfigurationClassPostProcessor.html. Không chắc chắn bạn đang sử dụng phiên bản nào.

+1

Câu hỏi về cấu hình xml - chuyển sang cấu hình Java (imo) không phải là câu trả lời hợp lệ :( –

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