2009-09-20 59 views
7

Có cách nào trong Mùa xuân mà tôi có thể tự động điền một danh sách có tất cả các loại đậu và một loại phụ của nó không? Tôi có phương thức setter trông giống như:Danh sách các loại đậu mùa xuân theo loại

setMyProp(List<MyType> list) 

Và tôi muốn tự động điền vào bất kỳ hạt nào của MyType và tất cả các lớp con của MyType.

Cảm ơn, Jeff

+0

Làm thế nào để bạn muốn danh sách này để làm việc với nguyên mẫu? Nếu nó chỉ chứa một thể hiện, có mỗi trường hợp được thêm vào (rò rỉ bộ nhớ) hoặc được quay trở lại bởi một số dạng danh sách tham chiếu yếu. –

+0

tất cả các hạt cà phê sẽ là đơn trong trường hợp của tôi –

Trả lời

24

Yup, bạn có thể thực hiện việc này. Các tài liệu xuân nói:

Nó cũng có thể cung cấp tất cả đậu của một loại đặc biệt từ ApplicationContext bằng cách thêm chú thích để một lĩnh vực hoặc phương pháp mà hy vọng một mảng của loại đó.

Lưu ý rằng nó cho biết bạn cần mong đợi một mảng chứ không phải danh sách. Điều này có ý nghĩa, bởi vì xóa kiểu chung chung có nghĩa là một danh sách có thể không hoạt động trong thời gian chạy. Tuy nhiên, tham dự kỳ thi sau đây đơn vị, trong đó hoạt động:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> 

    <bean class="test.Test.TypeB"/> 
    <bean class="test.Test.TypeC"/> 
    <bean class="test.Test.TypeD"/> 
</beans> 

và kiểm tra đơn vị này:

package test; 

@ContextConfiguration 
@RunWith(SpringJUnit4ClassRunner.class) 
public class Test { 

    private @Autowired List<TypeA> beans; 

    @org.junit.Test 
    public void test() { 
     assertNotNull(beans); 
     assertEquals(2, beans.size()); 
     for (TypeA bean : beans) { 
      assertTrue(bean instanceof TypeA); 
     } 
    }  

    public static interface TypeA {} 
    public static class TypeB implements TypeA {} 
    public static class TypeC extends TypeB {} 
    public static class TypeD {} 

} 

Vì vậy, chính thức, bạn đang phải autowire TypeA[], không List<TypeA>, nhưng danh sách hoạt động tốt.

0

Câu trả lời ngắn: không có.

Câu trả lời dài: Java Generics làm việc theo loại tẩy xoá, có nghĩa là khi chạy tham số đó chỉ đơn giản là một danh sách, không phải là một danh sách chung loại. Như vậy bạn không thể tìm ra rằng nó có nghĩa là loại MyType kiểu tham số để nó không thể thực hiện hành vi này.

Điều đó đang được nói, có những cách khác để thực hiện việc này. Rõ ràng nhất dường như là lắng nghe để tạo bean và sau đó nhìn thấy nếu chúng là của MyType (hoặc các lớp con) và sau đó giữ một tham chiếu.

Có thể có một số cách để thực hiện việc này. Một là creating a bean post-processor. Bằng cách này, bạn sẽ nhận được thông báo về mọi bean được tạo.

+3

Loại thông tin cho các tham số phương pháp không hoàn toàn bị xóa và vẫn có sẵn cho thời gian chạy. Bạn có thể truy cập thông qua phương thức getGenericParameterTypes của phương thức hoặc phương thức Constructor. –

+0

@mik: có nhưng anh ấy đang nói về một tham số trên một hàm không có thông tin như vậy. – cletus

5

Nếu có thể chấp nhận điền vào danh sách từ mã ứng dụng của bạn chứ không phải từ tệp định nghĩa bean bạn có thể sử dụng org.springframework.beans.factory.xml.XmlBeanFactory và yêu cầu "getBeansOfType(MyType.class)". Điều này cung cấp cho bạn tất cả các loại đậu (và loại phụ) của MyType.

+1

Điều này thực sự hiệu quả đối với tất cả các lớp thực thi ListableBeanFactory (http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/beans/factory/ListableBeanFactory.html#getBeansOfType%28java.lang.Class% 29) –

3

Nếu bạn có thể sử dụng @Autowired bên trong mã để được điền, bạn có thể sử dụng một cách an toàn cách được đề cập bởi nghệ sĩ. Nếu bạn nhấn mạnh vào cấu hình XML có một thư viện nhỏ gọi là Hera để đạt được điều này. cấu hình esentially của một kịch bản được mô tả bởi bạn trông như thế này:

<bean id="client" class=".."> 
    <property name="injectDynamicListHere"> 
     <hera:list class="my.custom.SuperType" /> 
    </property> 
</bean> 

này sẽ bơm tất cả đậu mùa xuân top-level thực hiện SuperType như List vào đậu client.

+0

tuyệt vời, cảm ơn. Tôi đã có thể sử dụng @Autowired trong mã, nhưng điều này là tốt để biết. –

+1

Có lẽ một điều nhỏ cần thêm là danh sách Hera tôn trọng chú thích @Ordered resp. thực hiện giao diện Ordered để cho phép xác định thứ tự của các bean được tiêm. –

0

Do mã di sản và mất tích @Autowired tôi giải quyết nó thích:

MyBean implements ApplicationContextAware{ 

    @Override 
    public void setApplicationContext(ApplicationContext ctx) throws BeansException { 
    final Map<String, HttpRequestHandlerTemplate> beansOfType = ctx.getBeansOfType(RequiredBean.class); 
    ... 
} 
Các vấn đề liên quan