2012-03-22 39 views
6

Tôi tự hỏi tại sao trong mùa xuân DI định nghĩa bean sau làm việc (tôi sử dụng bean instantiation with a static factory method và ổi của Suppliers.ofInstance):phương pháp Generic nhà máy ở Xuân DI

<bean id="keySupplier" class="com.google.common.base.Suppliers" 
    factory-method="ofInstance"> 
    <constructor-arg> 
    <value type="java.lang.String">someReallyLongValue <!-- note line break here --> 
    </value> 
    </constructor-arg> 
</bean> 

nhưng điều này không:

<bean id="keySupplier" class="com.google.common.base.Suppliers" 
    factory-method="ofInstance"> 
    <constructor-arg type="java.lang.String" value="someReallyLongValue" /> 
</bean> 

Nó ném theo ngoại lệ sau:

org.springframework.beans.factory.BeanCreationException: Lỗi creatin g đậu với tên 'userRepo' định nghĩa trong đường dẫn lớp tài nguyên:
(...)
phụ thuộc không được đáp ứng thể hiện qua tranh luận constructor với chỉ số 0 của loại [java.lang.Object]:
nhập nhằng các loại phương pháp nhà máy đối số - đã làm bạn chỉ định các tham chiếu bean đúng như các đối số phương thức của nhà máy?

Vấn đề là, trong trường hợp của tôi, khi tôi sử dụng định nghĩa bean đầu tiên với chuỗi rất dài như một giá trị dòng phá vỡ biên tập viên của tôi sau khi ký tự cuối cùng của chuỗi, gây rằng chuỗi được thông qua với thêm khoảng trắng-Suppliers.ofInstance và kết quả là nó phá vỡ mã của tôi.

Định nghĩa thứ hai sẽ nghiêm ngặt hơn về khoảng trắng nhưng đáng ngạc nhiên là nó không hoạt động (có thể không đối phó với kiểu chung, mặc dù loại được chỉ định trong thuộc tính type).

Tôi có thể buộc Spring bỏ qua khoảng trắng trong thẻ <value> bằng cách nào đó không?

Hoặc tôi có sử dụng <constructor-arg type="java.lang.String" value="someReallyLongValue" /> đúng cách không? Hoặc tôi nên nộp một vấn đề vì nó là một lỗi mùa xuân?

Tôi không muốn đưa ra bất kỳ giả định nào về chuỗi (ví dụ: sử dụng string.trim() tại đây).

+0

Trước tiên, định cấu hình trình chỉnh sửa XML của bạn để không tự động ngắt dòng chèn. Nếu không có tùy chọn như vậy, hãy thay đổi trình soạn thảo;) –

+0

@YvesMartin Tôi có thể cấu hình trình soạn thảo của mình để làm như vậy, nhưng nếu ai đó trong tương lai thực hiện định dạng (đơn giản 'CSf' trong Eclipse), tôi không thích thực tế là ứng dụng sẽ bị phá vỡ vì điều đó. – Xaerxess

+1

Vấn đề như vậy sẽ luôn tồn tại. Bạn nên di chuyển thông tin văn bản đó vào tệp thuộc tính. –

Trả lời

0

tôi sẽ khuyên bạn nên sử dụng một thuộc tính tập tin và sau đó sử dụng tài sản trong định nghĩa

Nhưng điều này không giải thích hành vi quan sát của bạn.

+0

Thực ra tôi đã chọn 'Nhà cung cấp ' không phải 'String' là phụ thuộc bởi vì tôi sẽ làm những công cụ nâng cao hơn với Nhà cung cấp (ghi nhớ giá trị được cung cấp, lấy String từ tệp đăng ký/thuộc tính, v.v.). Trường hợp cụ thể này là loại thực hiện giả lập của bean 'keySupplier' và đó là lý do tại sao tôi đã sử dụng nhà máy tĩnh' Suppliers.ofInstance' ở đây và tại sao tôi tò mò về sự thất bại tạo ra bean. – Xaerxess

0

Không chắc chắn 100% nhưng thử

<value index="0" [...] 

Không chắc những gì mã của bạn trông giống như nhưng theo thứ tự mà bạn đặt args constructor của bạn không được xem là trừ khi bạn xác định vị trí. Nếu bạn có nhiều nhà xây dựng, điều này có thể làm mọi thứ rối tung lên.

+0

Không, điều này không có ích ở đây - cũng có ngoại lệ tương tự. BTW bạn có nghĩa là '', phải không? – Xaerxess

6

Hai cấu hình không liên quan đến cùng một đường dẫn thực hiện trong Spring theo reference documentation about constructor resolution. Thất bại đến từ generics được sử dụng cho this instanceOf method mà tuyên bố Object làm đối số phương pháp.

mùa xuân đã làm các công việc sau để thành công:

  • tìm ra phương pháp đúng theo lập luận
  • chuyển đổi XML giá trị văn chương vào các đối tượng Java hoặc nhờ rõ ràng type khai hoặc dựa trên các loại phương pháp luận khi index được sử dụng

Logic tham gia là trong ConstructorArgumentValues giữ trong phương pháp getArgumentValue và trong cả hai getIndexedArgumentValue một d getGenericArgumentValue. Cả hai phương pháp đều sử dụng các bài kiểm tra để từ chối một số ValueHolder dựa trên thông tin có sẵn.

Trong trường hợp cấu hình thứ hai, phát hiện được lập chỉ mục được sử dụng và từ chối giá trị vì loại yêu cầu String không khớp chính xác với Object. Thử nghiệm này được thực hiện với ClassUtils.matchesTypeName không kiểm tra phân cấp loại.

Trong trường hợp cấu hình đầu tiên, giá trị chủ sở hữu sẵn sàng với đối tượng String và cơ chế đối số chung đồng ý vì giá trị được gán cho loại đối số phương thức được phát hiện.

Về mặt lý thuyết, biểu thức sau sẽ hoạt động vì loại được cung cấp để tạo đối tượng từ giá trị và chỉ mục được cung cấp để tránh bất kỳ phỏng đoán nào, ngay cả khi chỉ có một phương thức khớp.

<constructor-arg index="0" type="java.lang.String" value="queueName" /> 

May mắn thay, nó không cải thiện được gì, cùng một đường dẫn thực hiện vẫn được sử dụng. Tôi thực sự nghĩ rằng một cải tiến mùa xuân là bắt buộc. Bạn có thể tạo một số JIRA ticket.

+1

Sự khác nhau giữa '' và '' có được ghi lại ở đâu đó hoặc bạn đã kiểm tra mã nguồn chưa? – Xaerxess

+1

Tôi đã tạo [một vé] (https://jira.springsource.org/browse/SPR-9270), bây giờ tôi sẽ đợi nếu lỗi được xác nhận. – Xaerxess

+0

Tôi không coi đó là lỗi mà là cải tiến. Nhân tiện, biểu mẫu được đề xuất để thực hiện cấu hình này là sử dụng thẻ ""! –

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