Sử dụng mùa xuân @Autowired


218

Những ưu và nhược điểm của việc sử dụng @Autowired trong một lớp sẽ được kết nối bởi Spring là gì?

Để làm rõ, tôi đang nói cụ thể về chú thích @Autowired , không phải tự động nối dây trong XML.

Tôi có lẽ chỉ không hiểu nó, nhưng đối với tôi nó gần như là một mô hình chống - các lớp của bạn bắt đầu nhận thức được rằng chúng được gắn với một khung DI, thay vì chỉ là POJO. Có thể tôi là một kẻ háu ăn vì bị trừng phạt, nhưng tôi thích có cấu hình XML bên ngoài cho các bean và tôi thích có các dây dẫn 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 thông qua các chú thích thay vì XML có vẻ như nó sẽ dẫn đến rất nhiều tìm kiếm về "lớp nào được ánh xạ tới URL này?" "Ai đang xử lý việc này?". Tôi muốn có một nguồn cấu hình duy nhất
matt b

6
thuật ngữ "@Autowires" dường như gây hiểu nhầm ở đây. Vì bạn cũng có thể thực hiện tự động với cấu hình XML, câu hỏi ban đầu nên được đặt lại là "Ưu và nhược điểm của việc sử dụng chú thích mùa xuân". 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 tự động và ít hơn về các khía cạnh của việc sử dụng các chú thích.
Neeme Praks 11/03/2016

Câu trả lời:


253

Trong một thời gian dài, tôi tin rằng có một giá trị trong việc có một "cấu hình tập trung, khai báo, cấu hình" giống như các tệp xml mà tất cả chúng ta từng sử dụng. Sau đó, tôi nhận ra rằng hầu hết những thứ trong các tập tin không phải là cấu hình - nó không bao giờ được 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 mới có thể tìm kiếm toàn bộ tệp cấu hình . Và thực sự giá trị của việc hiểu toàn bộ hệ thống dây điện là gì, khi cùng một "dây dẫn" hầu hết được nhân đôi bởi các phụ thuộc trong mã? Vì vậy, thứ duy nhất tôi giữ là siêu dữ liệu (chú thích), vẫn là loại khai báo. Những không bao giờ thay đổi trong thời gian chạy và họ không bao giờ "cấu hình" dữ liệu mà ai đó sẽ thay đổi nhanh chóng - vì vậy tôi nghĩ việc giữ nó trong mã là tốt.

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

Ngay bây giờ tôi nghĩ lý do quan trọng nhất để sử dụng tính năng tự động là có một sự trừu tượng hóa ít hơn trong hệ thống của bạn để theo dõi. "Tên đậu" đã hết hiệu lực. Hóa ra tên bean chỉ tồn tại vì xml. Vì vậy, một lớp đầy đủ của các hướng dẫn trừu tượng (nơi bạn sẽ nối tên bean "foo" vào bean "bar") đã biến mất. Bây giờ tôi nối trực tiếp giao diện "Foo" vào bean của mình và việc triển khai được chọn theo cấu hình 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 các phụ thuộc và triển khai. Khi tôi thấy một phụ thuộc tự động trong mã của mình, tôi chỉ cần nhấn phím "đi đến thực hiện" trong IDE của mình và đưa ra 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 triển khai và tôi vào thẳng lớp. Có thể' việc triển khai nào đang được sử dụng (tôi cho rằng điều ngược lại gần với sự thật hơn với hệ thống dây xml - thật buồn cười khi cách nhìn của bạn thay đổi!)

Bây giờ bạn có thể nói rằng đó chỉ là một lớp rất đơn giản, nhưng mỗi lớp trừu tượng mà chúng ta thêm vào hệ thống của chúng ta làm tăng sự 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 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 để thử nghiệm và như vậy.

Tôi muốn nói rằng tự động hoàn toàn là ruby-on-rails của mùa xuân: Nó bao hàm 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 đều tuân theo. Với cấu hình XML, bạn cho phép sử dụng nhiều cấu hình nhất quán / không nhất quán có thể / có thể không được dự định. Tôi đã thấy rất nhiều cấu hình xml đi quá mức với sự không nhất quán - nó có được cấu trúc lại cùng với mã không? Nghĩ là không. Là những biến thể ở đó cho một lý do? 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 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 tôi gặp phải: Chúng tôi đã thay đổi một chút cách chúng tôi viết mã để làm cho nó tương tác mượt mà hơn với chế độ tự động: Kho lưu trữ của khách hàng không còn thực hiện Repository<Customer>giao diện chung mà chúng tôi tạo giao diện CustomerRepositorymở rộng Repository<Customer>. Đôi khi cũng có một hoặc hai mẹo khi phân lớp. Nhưng nó thường chỉ hướng chúng ta theo hướng gõ mạnh hơn, mà tôi thấy hầu như luôn luôn là một giải pháp tốt hơn.

Nhưng vâng, bạn đang buộc vào một phong cách đặc biệt của DI mà chủ yếu là mùa xuân. Chúng tôi thậm chí không tạo ra các setters công khai cho các phụ thuộc nữa (Vì vậy, bạn có thể lập luận rằng chúng tôi +1 trong bộ phận đóng gói / ẩn thông tin) Chúng tôi vẫn có một số xml trong hệ thống của chúng tôi, nhưng về cơ bản xml chỉ chứa các dị thường. Tự động hoàn toàn tích hợp độc đáo với xml.

Điều duy nhất chúng ta cần bây giờ là @Component, @Autowiredvà phần còn lại được bao gồm trong một JSR (như JSR-250 ), vì vậy chúng ta không phải kết hợp với mùa xuân. Đây là cách mọi thứ đã xảy ra trong quá khứ (những java.util.concurrentthứ nảy ra trong đầu), 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.


5
Javax.annotation / javax.inject được hỗ trợ bởi mùa xuân nên bạn không cần phải phụ thuộc mã vào Spring.
Michael Wiles

26

Đối với tôi đây là những gì tôi thích / không thích về Spring và tự động nối dây.

Ưu điểm:

  • Tự động nối dây được loại bỏ cấu hình XML khó chịu.
  • Sử dụng các chú thích dễ dàng hơn nhiều cho phép bạn tiêm trực tiếp bằng cách sử dụng các trường, phương thức setter hoặc hàm 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:

  • Việc sử dụng tự động nối dây và chú thích làm cho bạn phụ thuộc vào các thư viện Spring trong đó với cấu hình XML, bạn có thể chọn chạy cùng hoặc không có Spring. Giống như bạn đã nói, bạn trở nên gắn liền với khung DI.
  • Đồng thời tôi thích có thể 'đủ điều kiện' đậu, 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 tiêm cùng một hạt ở nhiều nơi, tôi đã thấy cùng một tên chuỗi được lặp lại. Đối 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 hệ thống tự động hầu như chỉ có tại nơi làm việc bởi vì chúng tôi phụ thuộc rất nhiều vào tích hợp Spring dù sao vấn đề phụ thuộc là phải khắc phục. Tôi đã làm việc trong một dự án Spring MVC sử dụng tự động nối dây 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 sở thích có được, khi bạn đã quen với nó, bạn sẽ nhận ra rằng nó hoạt động mạnh mẽ, dễ dàng và ít đau đầu như thế nào so với cấu hình XML.


3
Cấu hình xml sẽ bớt khó chịu hơn rất nhiều nếu bạn sử dụng Bộ công cụ Springsource miễn phí, có tính năng tự động hoàn thành, biểu đồ bean, v.v.
Sean Patrick Floyd

Tôi hoàn toàn đồng ý với bạn về việc hệ thống tự động trở nên 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à tôi nghĩ có lẽ tôi nên đi xuống con đường đó?
James111

15

Chúng tôi đang chuyển từ @Autowire trở lại cấu hình XML trong dự án lớn của chúng tôi. Vấn đề là hiệu suất bootstrap rất thấp. Trình quét tự động tải tất cả các lớp từ đường dẫn tìm kiếm tự động, vì vậy, rất nhiều lớp được tải một cách 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à một giải pháp tốt hơn để bắt đầu bối cảnh một phần, đó là một chiến thắng lớn Nhưng bạn có thể kết hợp những điều này khá dễ dàng bằng cách sử dụng @ Autowired / @ Tiêm trên các hàm tạo (nói cách khác, chuyển sang tiêm constructor).
krosenvold

6

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

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

Nó nên được làm việc, nhưng không phải là một giải pháp tốt đẹp.


Tôi đã mở một chủ đề riêng về vấn đề này và có một giải pháp với Spring @Profiles@Configuration: blog.springsource.org/2011/02/14/ Khăn Xem thêm chủ đề khác: stackoverflow.com/questions/13490393/
trộm

4

Tôi đã chuyển sang @Autowire. Việc duy trì cấu hình XML trên bất kỳ thứ gì khác ngoài một dự án nhỏ đã trở thành một nhiệm vụ theo đúng nghĩa 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 các chú thích Mùa xuân.


3

Tôi coi 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.

Các 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, vì các phụ thuộc không thể được thực hiện cuối cùng nữa, do các nhà xây dựng mặc định cần được cung cấp. Sự phụ thuộc cần phải được đưa vào thông qua setter công khai hoặc không được kiểm soát thông qua @Autowired. [thậm chí tiêm phụ thuộc tồi tệ hơn bị xâm phạm với các lớp khởi tạo sự phụ thuộc của chúng, tôi vẫn thấy điều này trong mã mới được viết!]. Ý tôi là không kiểm soát được, trong các hệ thống lớn, khi có nhiều triển khai (hoặc trẻ em) thuộc loại này, sẽ có nhiều sự tham gia hơn để hiểu cách triển khai nào là @Autowired, một sự phức tạp khiến việc điều tra lỗi khó hơn nhiều. Điều đó cũng có nghĩa là, được cho là bạn có một hồ sơ cho môi trường thử nghiệm và một hồ sơ khác cho sản xuất,

Tôi bám sát mặt đất nơi tôi khai báo (các) lớp cấu hình của mình, (cấu hình Spring dựa trên java bằng cách sử dụng @Configuration)

Tôi khai báo tất cả các bean của tôi một cách rõ ràng trong lớp cấu hình. Tôi chỉ sử dụng @Autowired trong (các) lớp cấu hình, mục đích là để hạn chế 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 mà quá trình quét mùa xuân chạy. (Điều đó tăng tốc đáng kể thời gian bắt đầu trong các dự án lớn)

Tôi cố gắng làm cho tất cả các lớp của mình trở nên bất biến, đặ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 mọi thứ buộc tôi phải cung cấp setters hoặc xóa từ khóa cuối cùng khỏi bản kê khai 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ó cũng buộc nhà phát triển phải 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ở thành lỗi biên dịch, giúp 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

  • Giúp dễ dàng cấu hình hơn vì chúng ta chỉ có thể sử dụng chú thích @Autowire
  • Không muốn sử dụng các phương thức setter, vì vậy lớp sẽ sạch hơn

Nhược điểm

  • Kết hợp chặt chẽ với tập tin xml mặc dù chúng tôi đang sử dụng DI
  • Khó tìm thấy triển khai (Nhưng nếu bạn sử dụng các ides tốt như intellij chắc chắn bạn có thể thoát khỏi điều này)

Theo kinh nghiệm cá nhân của tôi, 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.


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à Chú thích đã đạt được kết quả tương tự.

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

Chuyên nghiệp:

  • Xóa dòng vô dụng khỏi xml
  • Đơn giản hóa việc gỡ lỗi mã: khi bạn mở một lớp, 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ó 400 dòng XML trở lên có thể đọc được?

Nhược điểm:

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

0

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.