2011-10-15 33 views
14

Mùa xuân có hai loại DI: setter DI và DI xây dựng.Setter DI so với Constructor DI trong mùa xuân?

DI dựa trên nhà xây dựng sửa chữa thứ tự mà phụ thuộc cần phải được tiêm. Setter dựa trên DI không cung cấp này.

DI dựa trên Setter giúp chúng tôi chỉ tiêm phụ thuộc khi được yêu cầu, thay vì yêu cầu nó khi xây dựng.

Tôi không thấy bất kỳ khác biệt đáng kể nào khác, vì cả hai loại Spring DI đều cung cấp các tính năng giống nhau - cả setter và hàm tạo DI tiêm phụ thuộc khi mã khởi động. Cấp, constructor DI sẽ làm điều đó thông qua constructor trong khi setter DI sẽ thực hiện nó thông qua một setter ngay sau khi xây dựng đối tượng, nhưng nó không tạo ra bất kỳ sự khác biệt nào cho nhà phát triển về hiệu suất, vv. của tiêm phụ thuộc là tốt.

Tôi đang tìm một trường hợp trong đó một cung cấp một lợi thế khác biệt so với trường hợp khác hoặc nơi một loại hoàn toàn không sử dụng được.

+0

http://stackoverflow.com/questions/39890849/what-exactly-is-field-injection-and-how-to-avoid-it – GKislin

Trả lời

14

Khi nói đến mùa xuân ưu và nhược điểm cụ thể:

  • Constructor tiêm (từ định nghĩa) không cho phép bạn tạo ra phụ thuộc vòng tròn giữa đậu. Giới hạn này thực sự là một lợi thế của việc xây dựng injection - Spring có thể giải quyết các phụ thuộc vòng tròn khi setter injection được sử dụng mà bạn thậm chí không nhận thấy.

  • Mặt khác, nếu bạn sử dụng công cụ xây dựng tiêm CGLIB không thể tạo proxy, buộc bạn phải sử dụng proxy dựa trên giao diện hoặc trình tạo hàm giả không có arg. Xem: SPR-3150

+0

Cảm ơn Tomasz.Point1: - Mùa xuân có cung cấp lỗi thời gian chạy trong trường hợp thông tư không phụ thuộc? Point2: -Chỉ cần cố gắng hiểu với example.Are bạn nói rằng nếu tôi có lớp A đang sử dụng Class B như sự phụ thuộc trong hàm tạo của nó (lớp B không thực hiện giao diện) .Wont it be possible? –

+1

Hãy suy nghĩ về nó: nếu bean A yêu cầu một thể hiện của bean B khi khởi động và bean B yêu cầu một cá thể của bean A, không có cách nào để khởi tạo chúng. Khi Spring phát hiện tình huống như vậy nó ném một ngoại lệ khi bắt đầu. Tuy nhiên với setter/field injection Spring có thể tạo ra các instance và sau đó tiêm chúng, không có vấn đề gì trong tình huống này. –

+1

Nếu đây là một vấn đề phổ biến trong dự án của bạn, tuy nhiên, bạn có thể có những thứ khác phải lo lắng hơn kiểu DI. –

12

Bạn nên quyết định dựa trên cân nhắc thiết kế, chứ không phải cân nhắc công cụ (Spring). Thật không may, Spring đã huấn luyện cho chúng tôi sử dụng tiêm setter bởi vì khi nó được hình thành ban đầu, không có thứ như "chú giải" trong Java, và trong XML, công cụ tiêm setter và trông đẹp hơn nhiều. Hôm nay, chúng tôi được giải thoát khỏi những hạn chế đó, do đó cho phép nó trở thành một quyết định thiết kế một lần nữa. Đậu của bạn nên sử dụng tiêm xây dựng cho bất kỳ phụ thuộc được yêu cầu của đậu và setter tiêm cho phụ thuộc là tùy chọn và có một mặc định hợp lý, nhiều hơn hoặc ít hơn như OOD đã nói với chúng tôi từ đầu.

+1

Cảm ơn Ryan.As bạn đã nói "Đậu của bạn nên sử dụng tiêm xây dựng cho bất kỳ phụ thuộc được yêu cầu bởi đậu và setter tiêm cho phụ thuộc là tùy chọn và có một mặc định hợp lý" .Đó là những gì iam cố gắng hiểu ở đây về mùa xuân, ngay cả khi phụ thuộc là tùy chọn, khung vẫn sẽ tiêm nó ngay từ đầu bản thân. Vậy sự khác biệt của nó trong cuộc sống của nhà phát triển là gì? –

+0

* Khi * một cái gì đó được tiêm và * nếu * một cái gì đó được tiêm là hai câu hỏi riêng biệt. Phụ thuộc tùy chọn rơi vào bên "nếu". –

0

Ưu tiên tiêm setter.

Hãy nghĩ điều gì sẽ không có mùa xuân (như Ryan lưu ý). Bạn sẽ vượt qua các phụ thuộc trong constructor? Nếu có quá nhiều phụ thuộc thì điều này có vẻ sai. Mặt khác, hàm tạo có thể được sử dụng để thực thi trạng thái hợp lệ của đối tượng - yêu cầu tất cả các phụ thuộc và xác minh nếu chúng không phải là null.

Proxy là một thứ khác (Như Tomasz đã lưu ý) - bạn sẽ cần một hàm tạo giả để đánh bại toàn bộ ý tưởng.

Có tùy chọn 3 btw - trường tiêm. Tôi có xu hướng sử dụng nó, mặc dù nó không phải là một quyết định thiết kế tốt, bởi vì nó tiết kiệm một setter thêm, nhưng nếu điều này được sử dụng bên ngoài mùa xuân, tôi sẽ phải thêm setter.

+0

Trên thực tế, việc sử dụng công cụ tiêm xây dựng có lợi ích phụ của việc làm cho các hạt được thiết kế kém của bạn đau đớn rõ ràng vì các nhà thầu lớn. JDK proxy động không cần các hàm tạo mặc định. Các khung công tác khác đang hướng ra khỏi các nhà thầu mặc định hoặc chỉ yêu cầu một hệ thống riêng. Trường tiêm là lựa chọn thứ hai của tôi, nhưng sau đó có các bài kiểm tra ... –

+0

yup, cho các bài kiểm tra có ReflectionTestUtils. Đó là một chút xấu xí mặc dù – Bozho

2

Constructor Injection: Chúng tôi đang tiêm các phụ thuộc thông qua Constructor.

Nói chung, chúng tôi có thể sử dụng cho Phụ thuộc bắt buộc.

Nếu bạn sử dụng công cụ xây dựng, có một bất lợi được gọi là "Thông tin phụ thuộc".

Thông tin phụ thuộc: Giả sử A và B. A phụ thuộc vào B. B phụ thuộc vào A. Trong lần khởi tạo này sẽ không thành công. Tại thời điểm đó Setter tiêm là hữu ích.

Nếu trạng thái Đối tượng không nhất quán, nó sẽ không tạo đối tượng.

Setter Injection: Chúng tôi đang tiêm phụ thuộc thông qua phương pháp Setter.

Điều này hữu ích cho Phụ thuộc không bắt buộc.

Có thể tái tiêm phụ thuộc bằng cách sử dụng Setter Injection. Đó là không thể trong Tiêm bổ sung.

0

không, ngay cả khi việc xây dựng Tiêm xảy ra, quá trình tiêm vẫn hoạt động, nhưng chỉ giới hạn khởi tạo, tiêm setter là tùy chọn và linh hoạt. nhưng nó có thể chung cho các lớp tham số, một đậu mùa xuân với đậu mùa xuân khác

0

Vì bạn có thể kết hợp cả hai,
Constructor DI - và Setter dựa trên DI,
nó là một nguyên tắc nhỏ để sử dụng các đối số hàm tạo cho các phụ thuộc bắt buộc và các bộ định vị cho các phụ thuộc tùy chọn.


Lưu ý rằng việc sử dụng chú thích @Required trên trình đặt có thể được sử dụng để thực hiện các yêu cầu phụ thuộc.

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