2012-11-02 18 views
10

Tôi có một bean:Tại sao tôi cần thiết lập cho trường tự động/được tiêm?

<bean id="BasketLogic" class="efco.logic.EfcoBasketLogic" autowire="byType"> 
     <property name="documentLogic" ref="DocumentLogic" /> 
     <property name="stateAccess" ref="StateAccess" /> 
     <property name="contextAccess" ref="ContextAccess" /> 
    </bean> 

    <bean id="EfcoErpService" autowire="byType" class="efco.erp.service.EfcoErpServiceImpl"> 
    <constructor-arg ref="ErpConnector"/> 
    </bean> 

documentLogic, stateAccesscontextAccess được các lĩnh vực trên BasketLogicImpl

Và tôi không có <context:component-scan />

EfcoBasketLogic.java:

public class EfcoBasketLogic extends BasketLogicImpl { 

     @Inject 
     private EfcoErpService erpService; 
    ... 
    ... 
    ... 
} 

erpService là null, trừ khi tôi cung cấp một setter. Nhưng tại sao? Tôi nghĩ rằng một setter là không cần thiết, nơi autowiring đang diễn ra? Nó có thể được rằng BasketLogicImpl chịu trách nhiệm cho điều đó?

Trả lời

11

Bạn cần sử dụng setter vì chú thích không được phát hiện trừ khi mùa xuân được thông báo qua <context:component-scan /> hoặc <context:annotation-config />. Setter được phát hiện vì bạn đã chỉ định autowire="byType".

Bạn có thể tìm thấy câu hỏi này và câu trả lời hữu ích cũng như: When to use autowiring in Spring

+0

Nếu tôi làm như vậy một vấn đề mới xuất hiện -> _Không có loại bean duy nhất [xyz] được xác định: bean kết hợp đơn dự kiến ​​nhưng tìm thấy 5_. Đó là do một bean khác mà tôi tiêm một thuộc tính thông qua '' và có 5 bean thực hiện giao diện đó. Thuộc tính 'x' có chú thích @Inject. Vì vậy, nó có vẻ như định nghĩa rõ ràng không ghi đè lên các công cụ autowired? – GarfieldKlon

+0

'@ Inject' sẽ được giải quyết đúng nếu chỉ có một loại đậu đã cho hoặc một loại được đánh dấu là chính. Nếu bạn có nhiều loại cây hoán đổi cho nhau của loại đó, bạn cần phải tiêm theo tên bằng cách sử dụng '@ Resource' hoặc xml. – mrembisz

+0

Ngay cả khi tôi tiêm một cách rõ ràng bean đó thông qua ''? – GarfieldKlon

1

Trước hết, việc sử dụng <context:component-scan /> hoặc <context:annotation-config /> phép xuân để quét mã của bạn cho đậu đủ điều kiện để đáp ứng phụ thuộc, mà rất nhiều sẽ cải thiện nó là khả năng nối chúng chính xác, vì vậy tôi đề nghị thêm chúng vào tệp ngữ cảnh của bạn.

Thứ hai, bạn nên lưu ý rằng @Inject là chú thích chuẩn (nghĩa là đặc tả JSR-330). Có thể trộn và ghép các chú thích mùa xuân với các chú thích chuẩn, nhưng hành vi có thể thay đổi khi làm như vậy. @Named thường được ghép nối với @Inject để khớp các thành phần với các phụ thuộc (cả JSR-330). Xem chi tiết reference để biết chi tiết và tham khảo Bảng 4.6 để biết các nhận xét sử dụng.

Nhưng để trả lời trực tiếp câu hỏi của bạn, "tại sao tôi cần thiết lập khi không sử dụng quét thành phần", là bạn không sử dụng tính năng quét thành phần. Bạn đang yêu cầu Spring tiêm một phụ thuộc "byType", nhưng không cho phép Spring quét mã của bạn cho các thành phần thuộc loại đó. Lý do setter hoạt động là kiểu của đối số setter được tiêm có thể được Spring phát hiện trong bytecode được biên dịch (tức là siêu dữ liệu), và do đó nó giải quyết thành công yêu cầu của bạn.

+0

FYI: Khi sử dụng '', hãy chắc chắn rằng bạn thiết lập thuộc tính base-package ở thư mục gốc của phân cấp lớp của bạn, nơi các lớp bean được khai báo (thông qua @Named hoặc @Autowired). Ví dụ: pmhargis

0

Hiểu biết của tôi là cấu hình XML ghi đè cấu hình chú thích. Thực tế là autowire = "byType" được ghi đè ghi tự động, tìm kiếm sự hiện diện của phương thức setter để tiêm phụ thuộc.

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