2009-03-11 24 views
200

Ưu và khuyết điểm của việc sử dụng @Autowired trong lớp học sẽ được kết nối bằng Spring là gì?Spring @Autowired usage

Chỉ cần làm rõ, tôi đang nói cụ thể về chú thích @Autowired, không tự động kết nối trong XML. Tôi có lẽ chỉ không hiểu nó, nhưng với tôi nó gần như có vẻ như một mô hình chống - các lớp học của bạn bắt đầu nhận thức được rằng chúng được gắn với một khuôn khổ DI, chứ không phải chỉ là POJO. Có lẽ tôi là một glutton cho hình phạt, nhưng tôi thích có cấu hình XML bên ngoài cho đậu, và tôi muốn có wirings rõ ràng, vì vậy tôi biết chính xác những gì có dây ở đâu.

+4

Tôi cũng quan tâm đến chủ đề này - định cấu hình ứng dụng MVC của bạn qua chú thích thay vì XML có vẻ như nó sẽ dẫn đến nhiều tìm kiếm "lớp nào được ánh xạ tới URL này?" "ai đang xử lý cái này?" Tôi muốn có một nguồn cấu hình đơn lẻ –

+5

thuật ngữ "@Autowiring" có vẻ gây hiểu nhầm ở đây.Vì bạn cũng có thể làm autowiring với cấu hình XML, câu hỏi ban đầu nên được rephrased là "Ưu và nhược điểm của việc sử dụng các chú thích Spring". Câu trả lời được cung cấp tập trung nhiều hơn vào các khía cạnh của autowiring và ít hơn về khía cạnh của việc sử dụng chú thích. –

+0

Bản sao có thể có của [Hiểu mùa xuân @Được sử dụng hết hạn] (https://stackoverflow.com/questions/19414734/understanding-spring-autowired-usage) – tkruse

Trả lời

244

Trong một thời gian dài tôi tin rằng có một giá trị trong việc có một "tập trung, khai báo, cấu hình" như các tập tin xml tất cả chúng ta sử dụng để sử dụng. Sau đó, tôi nhận ra rằng hầu hết các nội dung trong các tệp không phải là cấu hình - nó không bao giờ bị thay đổi ở bất cứ đâu sau khi phát triển. Sau đó, tôi nhận ra rằng "tập trung" chỉ có giá trị trong các hệ thống khá nhỏ - chỉ trong các hệ thống nhỏ, bạn sẽ có thể grok một tập tin cấu hình như một toàn bộ. Và cái gì thực sự là giá trị của sự hiểu biết về hệ thống dây điện như một tổng thể, khi cùng một "dây" được sao chép chủ yếu bởi các phụ thuộc trong mã? Vì vậy, điều duy nhất tôi giữ là siêu dữ liệu (chú thích), mà vẫn là loại khai báo. Những thay đổi này không bao giờ thay đổi khi chạy và chúng là không bao giờ "cấu hình" dữ liệu mà ai đó sẽ thay đổi khi đang di chuyển - vì vậy tôi nghĩ việc giữ mã trong mã là tốt đẹp.

Tôi sử dụng toàn bộ hệ thống tự động đấu dây càng nhiều càng tốt. Tôi thích nó. Tôi sẽ không quay trở lại mùa xuân kiểu cũ trừ khi bị đe dọa tại điểm súng. Lý do tôi thích hoàn toàn @Autowired đã thay đổi theo thời gian.

Ngay bây giờ tôi nghĩ rằng lý do quan trọng nhất để sử dụng autowiring là có ít trừu tượng hơn trong hệ thống của bạn để theo dõi. "Tên đậu" đã biến mất một cách hiệu quả. Nó chỉ ra tên đậu chỉ tồn tại vì xml. Vì vậy, một lớp đầy đủ các indirections trừu tượng (nơi bạn sẽ dây bean-tên "foo" vào đậu "bar") đã biến mất. Bây giờ tôi nối giao diện "Foo" vào bean của tôi trực tiếp, và việc triển khai thực hiện được chọn theo profile thời gian chạy. Điều này cho phép tôi làm việc với mã khi truy tìm phụ thuộc và triển khai. Khi tôi thấy một phụ thuộc tự động trong mã của tôi, tôi chỉ có thể nhấn phím "đi để thực hiện" trong IDE của tôi và lên đến danh sách các triển khai đã biết. Trong hầu hết các trường hợp, chỉ có một lần triển khai và tôi vào thẳng lớp học. Không thể đơn giản hơn nhiều, và tôi luôn biết chính xác những gì đang được sử dụng (tôi cho rằng điều ngược lại gần với sự thật với xml hệ thống dây điện - vui như thế nào quan điểm của bạn thay đổi!)

Bây giờ bạn có thể nói rằng nó chỉ là một lớp rất đơn giản, nhưng mỗi lớp trừu tượng mà chúng tôi thêm vào hệ thống của chúng tôi tăng độ phức tạp. Tôi thực sự không nghĩ rằng xml đã từng thêm bất kỳ giá trị thực nào vào bất kỳ hệ thống nào mà tôi đã làm việc cùng.

Hầu hết các hệ thống tôi từng làm việc chỉ có một cấu hình của môi trường thời gian chạy sản xuất. Có thể có các cấu hình khác để kiểm tra và vân vân.

Tôi muốn nói rằng autowiring đầy đủ là ruby-on-rails của mùa xuân: Nó bao gồm các khái niệm rằng có một mô hình sử dụng bình thường và phổ biến mà hầu hết các trường hợp sử dụng theo. Với cấu hình XML, bạn cho phép nhiều mức sử dụng cấu hình nhất quán/không phù hợp có thể/không được dự định. Tôi đã nhìn thấy rất nhiều cấu hình xml đi overboard với mâu thuẫn - nó có được refactored cùng với mã? Tư tưởng không. Những biến thể đó có lý do không? Thường thì không.

Chúng tôi hầu như không sử dụng vòng loại trong cấu hình của mình và tìm ra các cách khác để giải quyết các tình huống này. Đây là một "nhược điểm" rõ ràng mà chúng ta gặp phải: Chúng ta đã thay đổi một chút cách chúng ta mã hóa để làm cho nó tương tác mượt mà hơn với autowiring: Kho lưu trữ của khách hàng không còn thực hiện giao diện chung Repository<Customer> nhưng chúng ta tạo một giao diện CustomerRepository mở rộng Repository<Customer>. Đôi khi cũng có một hoặc hai mẹo khi nói đến phân lớp. Nhưng nó thường chỉ chỉ cho chúng ta theo hướng gõ mạnh hơn, mà tôi tìm thấy hầu như luôn luôn là một giải pháp tốt hơn.

Nhưng có, bạn đang liên kết với một kiểu DI cụ thể mà chủ yếu là mùa xuân. Chúng tôi thậm chí không làm cho người định cư công cộng cho phụ thuộc nữa (Vì vậy, bạn có thể tranh luận rằng chúng tôi đang +1 trong bộ phận đóng gói/thông tin ẩn) Chúng tôi vẫn có một số xml trong hệ thống của mình, nhưng xml về cơ bản là chỉ có những bất thường . Full autowiring tích hợp độc đáo với xml.

Điều duy nhất chúng tôi cần bây giờ là dành cho @Component, @Autowired và phần còn lại được bao gồm trong JSR (như JSR-250), vì vậy chúng tôi không phải gắn liền với mùa xuân. Đây là cách mọi thứ đã xảy ra trong quá khứ (các công cụ java.util.concurrent lò xo để tâm trí), vì vậy tôi sẽ không hoàn toàn ngạc nhiên nếu điều này xảy ra một lần nữa.

+4

javax.annotation/javax.inject được hỗ trợ bởi spring nên bạn không cần phải có sự phụ thuộc mã vào Spring. –

26

Đối với tôi, đây là những gì tôi thích/không thích về Mùa xuân và tự động đấu dây.

Ưu điểm:

  • Auto-dây được thoát khỏi cấu hình XML khó chịu.
  • Dễ dàng hơn nhiều khi sử dụng chú thích cho phép bạn chèn trực tiếp bằng các trường, phương thức setter hoặc phương thức khởi tạo. Cũng cho phép bạn chú thích và 'đủ điều kiện' đậu được tiêm của bạn.

Nhược điểm:

  • Sử dụng tính năng tự động hệ thống dây điện và các chú thích làm cho bạn phụ thuộc vào thư viện mùa xuân nơi như với cấu hình XML, bạn có thể chọn để chạy có hoặc không có mùa xuân. Như bạn đã nói, bạn trở nên gắn với một khuôn khổ DI.
  • Đồng thời tôi thích có thể đậu 'đủ điều kiện', với tôi điều này làm cho mã thực sự lộn xộn. Nếu bạn cần phải tiêm cùng một hạt ở nhiều nơi, tôi đã nhìn thấy cùng một tên chuỗi lặp đi lặp lại trên tất cả. Với tôi điều này dường như có khả năng xảy ra lỗi.

Tôi đã bắt đầu sử dụng tự động chuyển mạch gần như độc quyền tại nơi làm việc vì chúng tôi phụ thuộc quá nhiều vào tích hợp Spring dù sao vấn đề phụ thuộc là tranh luận. Tôi đã làm việc trên một dự án Spring MVC đã sử dụng hệ thống dây dẫn tự động rộng rãi và hơi khó khăn để quấn đầu tôi.

Tôi nghĩ rằng tự động nối dây là một hương vị có được, một khi bạn quen với nó, bạn nhận ra mức độ mạnh mẽ, dễ dàng và ít đau đầu hơn so với cấu hình XML.

+3

cấu hình xml khó chịu hơn rất nhiều nếu bạn sử dụng Bộ công cụ Springsource miễn phí, tính năng tự động hoàn thành, đồ thị đậu vv –

+0

Tôi hoàn toàn đồng ý với bạn về việc tự động nối dây bị lộn xộn và phụ thuộc vào các thư viện mùa xuân! Tôi chưa bao giờ sử dụng cấu hình XML và đang nghĩ rằng tôi có lẽ nên đi xuống con đường đó? – James111

4

Tôi đã chuyển sang @Autowire. Việc duy trì cấu hình XML trên bất kỳ thứ gì ngoài một dự án nhỏ đã trở thành một nhiệm vụ vì quyền riêng của nó và sự hiểu biết nhanh chóng bị suy giảm.

IntelliJ cung cấp hỗ trợ tốt (không hoàn hảo) cho chú thích mùa xuân.

14

Chúng tôi đang chuyển từ cấu hình @Autowire trở lại thành XML trong dự án lớn của chúng tôi.Vấn đề là hiệu năng bootstrap rất thấp. Trình quét tự động tải tất cả các lớp từ classpath tìm kiếm tự động, vì vậy, rất nhiều lớp được nạp háo hức trong quá trình khởi tạo Spring.

+1

Tôi đã thấy rằng javaconfig thậm chí có thể là giải pháp tốt hơn để bắt đầu một phần bối cảnh, đó là một chiến thắng lớn Nhưng bạn có thể kết hợp chúng một cách dễ dàng bằng cách sử dụng @ Autowired/@ Inject trên các nhà xây dựng (nói cách khác, chuyển sang constructor injection). – krosenvold

3

Việc thực hiện chủ đề này là, cấu hình xml làm giảm độ rõ của mã, đặc biệt là trong các hệ thống lớn.

Chú thích như @Component khiến mọi thứ trở nên tồi tệ hơn. Nó thúc đẩy các nhà phát triển để làm cho các đối tượng có thể thay đổi được, vì các phụ thuộc không thể được thực hiện cuối cùng nữa, cho rằng các nhà xây dựng mặc định cần phải được cung cấp. Phụ thuộc cần phải được tiêm thông qua setter công cộng, hoặc không kiểm soát được thông qua @Autowired. [thậm chí tiêm phụ thuộc tồi tệ hơn cũng bị tổn hại với các lớp khởi tạo các phụ thuộc của chúng, tôi vẫn thấy điều này trong mã mới được viết!]. Bởi không kiểm soát được tôi có nghĩa là, trong các hệ thống lớn, khi có nhiều triển khai (hoặc trẻ em) có sẵn, nó sẽ tham gia nhiều hơn để hiểu được những triển khai nào đã được thực hiện, một sự phức tạp làm cho việc điều tra lỗi khó khăn hơn nhiều. Nó cũng có nghĩa là, bạn cho rằng bạn có một hồ sơ cho môi trường thử nghiệm và một môi trường khác để sản xuất, lỗi sản xuất của bạn sẽ chỉ xảy ra khi nó đau nhất - trong sản xuất, thay vì có thể phát hiện lỗi trong môi trường thử nghiệm, hoặc thậm chí tốt hơn, thời gian biên dịch!

tôi dính vào mặt đất giữa nơi tôi tuyên bố lớp học của tôi cấu hình (es), (java dựa cấu hình Spring sử dụng @Configuration)

Tôi tuyên bố tất cả đậu của tôi một cách rõ ràng trong các lớp cấu hình (es). Tôi chỉ sử dụng @Autowired trong lớp cấu hình, mục đích là giới hạn sự phụ thuộc vào Spring vào (các) lớp cấu hình:

@Configuration nằm trong một gói cụ thể, đó là nơi duy nhất quét mùa xuân . (Điều đó đẩy nhanh thời gian bắt đầu đáng kể trong các dự án lớn)

Tôi cố gắng làm cho tất cả các lớp không thay đổi, đặc biệt là đối tượng dữ liệu, JPA, Hibernate và Spring, cũng như nhiều thư viện tuần tự hóa dường như làm suy yếu điều này. Tôi tránh xa bất cứ điều gì buộc tôi phải cung cấp người định cư hoặc xóa từ khóa cuối cùng khỏi tuyên bố tài sản của tôi.

Giảm khả năng thay đổi đối tượng sau khi chúng được tạo, giảm đáng kể các lỗi trong hệ thống lớn cũng như giảm thời gian tìm lỗi khi tồn tại.

Dường như nó buộc nhà phát triển thiết kế tốt hơn sự tương tác giữa các phần khác nhau của hệ thống. Các vấn đề và lỗi ngày càng trở nên lỗi biên dịch hơn, làm giảm thời gian lãng phí và cải thiện năng suất.

1

Dưới đây là một số kinh nghiệm
Ưu

  • Làm cho dễ dàng hơn để cấu hình bởi vì chúng ta chỉ có thể sử dụng @Autowire chú thích
  • Không muốn sử dụng phương pháp setter, vì vậy lớp sẽ có nhiều sạch

Nhược điểm

  • chặt cặp đôi vào tập tin xml mặc dù chúng ta đang sử dụng DI
  • cứng để tìm thực hiện (Nhưng nếu bạn của bạn sử dụng IDEs tốt như IntelliJ chắc chắn bạn có thể thoát khỏi điều này)

Tính cá nhân của tôi kinh nghiệm tôi không sử dụng chú thích @AutoWire nhiều nhưng trong các trường hợp thử nghiệm.

6

Đã có rất ít thảo luận về việc chuyển đổi môi trường. Hầu hết các dự án tôi đã làm việc trên nó là một vấn đề thực sự để tiêm phụ thuộc tùy thuộc vào môi trường chúng tôi đang làm việc trên. Với cấu hình xml khá đơn giản với Spring EL, và tôi không biết bất kỳ giải pháp tốt nào có chú thích. Tôi vừa tìm ra một:

@Value("#{${env} == "production" ? realService : dummyService}") 
    private SomeService service; 

Nó phải hoạt động, nhưng không phải là giải pháp tốt đẹp.

+0

Tôi đã mở một chuỗi riêng về điều này và có giải pháp với Spring '@ Profiles' và' @ Configuration': http://blog.springsource.org/2011/02/14/spring-3-1-m1- giới thiệu hồ sơ/Xem thêm các chủ đề khác: http://stackoverflow.com/questions/13490393/annotation-driven-dependency-injection-which-handles-different-environments – BTakacs

1

Tôi thực sự thích viết bằng chú thích thay vì XML. Theo hướng dẫn sử dụng Spring và các phiên bản cuối cùng, XML và Annotation đạt được kết quả tương tự.

Đây là danh sách của tôi

Pro:

  • Di dòng vô ích từ xml
  • Đơn giản hóa gỡ lỗi mã: khi bạn mở một lớp học, bạn có thể đọc những gì bạn có trong lớp
  • Phát triển nhanh hơn, một dự án có từ 400 dòng XML trở lên có thể đọc được?

Nhược điểm:

  • Không phải là tiêu chuẩn thực hiện Java, nhưng bạn có thể chuyển sang sử dụng @Inject, mà là một tiêu chuẩn Java Api, vì vậy đậu vẫn là một POJO
  • Bạn có thể không chỉ đơn giản sử dụng ở khắp mọi nơi , kết nối db e như vậy, nhưng nó chỉ là một ý kiến, tôi thích có một nơi mà đọc tất cả các cấu hình.
0

Vì sự hiểu biết của tôi @Autowired là cách tốt nhất để sử dụng khi tham khảo giao diện và sử dụng chức năng ghi đè của nó, nhưng tôi chỉ thấy vấn đề với điều này đôi khi được gán cho null khi chạy.

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