2009-12-30 35 views
9

thể Duplicates:
What is dependency injection?
What exactly is Spring for?Dependency Injection & Spring Framework là gì?

Tôi muốn biết Spring Framework là gì? Tại sao và khi nào nên sử dụng nó trong phát triển Java Enterprise? Câu trả lời sẽ là "Khung tiêm phụ thuộc". Được rồi, chúng ta có lợi thế gì khi sử dụng khung tiêm phụ thuộc? Ý tưởng mô tả các lớp với các giá trị setter và/hoặc các tham số hàm tạo có vẻ lạ đối với tôi. Tại sao lại như vậy? Bởi vì chúng ta có thể thay đổi các thuộc tính mà không biên dịch lại dự án? Đó là tất cả những gì chúng ta đạt được?

Sau đó, chúng ta nên mô tả những đối tượng nào trong beans.xml? Tất cả các đối tượng hoặc chỉ một vài?

Câu trả lời đơn giản nhất được chào đón

+3

Sau đó, những gì bạn đang tìm kiếm là một bài viết về vấn đề chứ không phải là câu trả lời SO. – Bozho

+0

Tôi không tìm kiếm một bài viết về vấn đề AS I ALREADY TRIỂN SÁCH TỐT NHẤT được xuất bản về chủ đề này. Tôi muốn biết ý kiến ​​của những người sử dụng nó trong công việc hàng ngày. – EugeneP

+0

Vâng, nó hoạt động. –

Trả lời

18

Chúng tôi sử dụng Dependency Injection (DI) để thực hiện lỏng khớp nối. Sự lựa chọn của bất kỳ DI Container đặc biệt không phải là quan trọng.Mỗi lần bạn tạo một thể hiện của một lớp bằng cách sử dụng từ khóa new, bạn sẽ kết hợp chặt chẽ mã của bạn với lớp đó và bạn sẽ không thể thay thế việc triển khai cụ thể đó bằng một phiên bản khác (ít nhất là không biên dịch lại mã).

này sẽ giống như thế này trong C# (nhưng sẽ tương đương trong Java):

public class MyClass 
{ 
    public string GetMessage(int key) 
    { 
     return new MessageService().GetMessage(key) 
    } 
} 

Điều này có nghĩa rằng nếu bạn sau này muốn sử dụng một MessageService khác nhau, bạn có thể không.

Mặt khác, nếu bạn tiêm giao diện vào lớp và tuân theo Liskov Substition Principle, bạn sẽ có thể thay đổi người tiêu dùng và dịch vụ một cách độc lập.

public class MyClass 
{ 
    private readonly IMessageService messageService; 

    public MyClass(IMessageService messageService) 
    { 
     if(messageService == null) 
     { 
      throw new ArgumentNullException("messageService"); 
     } 

     this.messageService = messageService; 
    } 

    public string GetMessage(int key) 
    { 
     return this.messageService.GetMessage(key) 
    } 
} 

Mặc dù điều này có vẻ phức tạp hơn, chúng ta đã cố gắng làm theo các Single Responsibility Principle bằng cách đảm bảo rằng mỗi cộng tác viên không chỉ có một điều, và rằng chúng ta có thể thay đổi cả hai độc lập với nhau.

Hơn nữa, giờ đây chúng tôi có thể thay đổi hành vi của MyClass mà không thay đổi chính lớp đó, do đó tôn trọng Open/Closed Principle.

11

Cấu hình lại được ghi đè. Điều quan trọng nhất bạn nhận được từ việc sử dụng DI là khả năng thử nghiệm. Vì các lớp của bạn không phụ thuộc vào việc triển khai nhưng trên các phép trừu tượng, bạn có thể thay thế chúng bằng mocks/stubs trong các bài kiểm tra đơn vị của bạn.

Ví dụ

Without DI:

class SaleAction{ 

private BillingService billingService; 

public SaleAction(){ 
    billingService = new CreditCardService(); //dependency is hardcoded 
} 

public void pay(long amount){ 
    //pre payment logic 
    billingService.pay(amount); 
    //post payment logic 
} 

} 

Trong ví dụ rằng giả sử bạn muốn kiểm tra đơn vị trước thanh toán logic và sau thanh toán logic của SaleAction ... bạn có thể không phải vì SaleAction là kết hợp với CreditCardService và có thể chạy thử nghiệm của bạn sẽ tạo ra các khoản thanh toán giả mạo.

Bây giờ ví dụ tương tự với DI:

class SaleAction{ 

    private BillingService billingService; 

    public SaleAction(BillingService service){ 
     billingService = service; //DI 
    } 

    public void pay(long amount){ 
     //pre payment logic 
     billingService.pay(amount); 
     //post payment logic 
    } 

    } 

Bây giờ SaleAction được tách riêng từ bất kỳ thực hiện, có nghĩa là trong thử nghiệm của bạn, bạn có thể làm SaleAction action = new SaleAction(new DummyBillingService());.

Hy vọng rằng sẽ giúp, còn bài viết về DI, được viết bởi Martin Fowler mà bạn có thể tìm here

+0

hiệu quả bạn đang nói rằng các khuôn khổ DI, ví dụ: Mùa xuân, được đánh giá cao vì nó tầm thường để thay thế các phụ thuộc với mocks trong mã mà không có một khung công tác.việc tạo ra những mocks có thể được tham gia khá nhiều nhưng tôi không thấy bất kỳ lợi thế trong việc có thể trao đổi chúng trong và ngoài cho mocks thay thế. –

+4

không dựa vào việc triển khai cụ thể là cốt lõi của OOP, không chỉ của DI. – Bozho

+0

Tôi không nói rằng các khung được đánh giá quá cao. DI là bắt buộc để thử nghiệm đơn vị, và thử nghiệm đơn vị là bắt buộc để phát triển phần mềm. –

3

Here's a good article giải thích những ý tưởng của mùa xuân. (Theo Rod Johnson, người sáng lập khung công tác Spring)

1

Ý kiến: Tìm hiểu xem bạn đang cố giải quyết vấn đề gì với DI và thực hiện một khuôn khổ phù hợp nhất. Mùa xuân có thể thêm vào nhiều phức tạp cho vấn đề của bạn.

(Một trong những first articles about DI by Martin Fowler. Tôi nghĩ rằng hạn DI được đặt ra trong bài viết này.)

3

Mùa xuân đã trở thành một khuôn khổ lớn, điều này có thể gây nhầm lẫn cho bạn nếu bạn chỉ cố gắng quấn đầu xung quanh việc tiêm phụ thuộc. Dự án Google Guice rất nhỏ và chỉ thực hiện DI với Java thuần - không có XML và không có phần bổ sung. Có một video giới thiệu tuyệt vời giải thích DI quá. http://code.google.com/p/google-guice/

+0

@Ken Fox. Không không. Tôi sẽ sử dụng Spring. DI đã được đề cập bởi vì nó tạo thành cơ sở của Spring Framework. Tôi không quan tâm đến DI, tôi quan tâm chủ yếu đến chức năng Spring. nhưng tôi cần phải biết những gì đẻ trong cơ sở. – EugeneP

+1

Mùa xuân luôn là một khuôn khổ lớn, nhiều hơn DI. AOP đã có hóa đơn như nhau kể từ ngày đầu tiên, như có các thư viện. Để nói rằng Spring và Guice map one-to-one là không chính xác như nói giống nhau cho Spring MVC và Struts. Mùa xuân bao gồm chức năng tương đương với cả hai và nhiều hơn nữa. – duffymo

+0

@Ken Fox. Tất cả các quyền, tôi không thực sự hiểu được AOP, tôi đã đọc rằng nó đề cập đến "mối quan tâm crosscutting", những thứ như đăng nhập xảy ra trong hầu như tất cả các phương pháp của lớp. Nhưng nói với tôi, được rồi, có AOP. Nhưng nó không thay thế DI, phải không? – EugeneP

2

Tôi nghĩ tôi có thể giải quyết vấn đề, mặc dù tôi không chắc chắn rằng mọi câu trả lời đều thỏa đáng.

Câu trả lời đơn giản là mùa xuân là sự kết hợp của công nghệ:

  1. dependency injection, trong đó sử dụng các nguyên tắc Hollywood để giúp bạn giữ cho giao diện và thực hiện riêng biệt;
  2. lập trình hướng khía cạnh, cách ly mối quan tâm cắt chéo thành các mô-đun mà bạn có thể áp dụng theo cách khai báo. "Xin chào thế giới" của AOP đang đăng nhập, nhưng tất cả đều trên Spring (ví dụ: giao dịch, proxy động để truy cập từ xa, bảo mật, v.v.) Hãy suy nghĩ các bộ lọc servlet và bạn sẽ có ý tưởng;
  3. thư viện để trợ giúp các tác vụ phổ biến như kiên trì (JDBC, Hibernate, iBatis, JDO, JPA, v.v.), từ xa (RMI, HTTP, dịch vụ web), nhắn tin asynch (POJOs thông báo), xác thực và ràng buộc, web MVC (Spring or Struts), các tiện ích như email, lên lịch, bảo mật, v.v.

Nhưng câu trả lời sâu hơn là bạn đang nhận được lợi ích từ kinh nghiệm của Rod Johnson với tư cách là nhà tư vấn về các dự án Java EE. Anh ta chưng cất những gì đã làm việc cho anh ấy trên các hợp đồng biểu diễn của anh ấy vào Giao diện 21/Mùa xuân, và bây giờ bạn có thể có được lợi ích của tất cả những điều đó miễn phí.

Nhóm Spring viết mã được thiết kế, kiểm tra và tuân theo các tiêu chuẩn nghiêm ngặt hơn bất kỳ thứ gì tôi từng viết. (Hãy tưởng tượng Juergen Hoeller browbeating Rod Johnson vì mã của anh ấy không đáp ứng được tiêu chuẩn trước khi check-in.) Tôi có thể dựa vào mã khung của họ khi tôi sử dụng nó và tập trung vào vấn đề kinh doanh của tôi. Tôi không viết mã tấm nồi hơi một lần nữa và một lần nữa.

Đối với tôi, Spring là nhiều hơn về mẫu kiến ​​trúc hoạt động như một hướng dẫn để tạo ứng dụng web.Một số người có thể nói rằng nó được thiết kế quá mức, và đối với một số vấn đề họ đúng, nhưng đối với loại vấn đề mà tôi phải đối mặt với một cách thường xuyên Mùa xuân chỉ là vé.

Đối với subquestions:

gì chúng tôi có lợi thế khi sử dụng khuôn khổ dependency injection?

Đối tượng không phải chịu trách nhiệm quản lý phụ thuộc của họ. Bối cảnh ứng dụng của mùa xuân thực sự chỉ là một mô hình nhà máy lớn từ GoF. Nó khuyến khích bạn thiết kế một giao diện để bạn có thể thay đổi việc triển khai khi cần thiết. Giao diện kiên trì của bạn có thể sử dụng một thực hiện JDBC ngày hôm nay, Hibernate vào ngày mai; bạn có thể quyết định tự động tạo proxy để quản lý hành vi giao dịch của nó. Không có mã khách hàng nào phải thay đổi nếu bạn mã hóa vào một giao diện.

Ý tưởng mô tả các lớp có giá trị setter và/hoặc tham số hàm tạo có vẻ lạ đối với tôi. Tại sao vậy? Bởi vì chúng ta có thể thay đổi các thuộc tính mà không biên dịch lại dự án ? Đó là tất cả những gì chúng ta đạt được?

Lạ? Bạn không sử dụng các thuộc tính hoặc các hàm tạo trong mã của bạn? Bạn làm điều đó bởi vì đó là cách hầu hết các lớp Java được viết. Spring chỉ sử dụng những cơ chế đó như một cách để cung cấp sự phụ thuộc cho lớp.

Sau đó, chúng ta nên mô tả những đối tượng nào trong beans.xml? Tất cả các đối tượng hoặc chỉ một vài?

Chỉ những hạt có phụ thuộc. Tôi vẫn gọi "mới" cho các đối tượng địa phương cho một phương pháp cụ thể. Chúng được tạo, sử dụng và thu thập rác trong phạm vi phương thức. Những nhu cầu đó không thuộc sự kiểm soát của Spring.

+0

Tôi không thể nói câu trả lời của bạn bao gồm tất cả các câu hỏi phụ của tôi, nhưng vẫn thú vị khi đọc nó. +1 – EugeneP

+0

Xem liệu các bổ sung có tốt hơn không. – duffymo

1

Đây là một good video do Bob Lee đưa ra và hai trong số các nghiên cứu của ông về Guice (Guice là khuôn khổ tiêm phụ thuộc như Mùa xuân). 10 phút đầu tiên hoặc lâu hơn là về lý do tại sao Guice (hoặc tiêm phụ thuộc) sẽ tốt hơn so với các nhà máy thay thế (Nhà máy) để nó không chỉ là về Guice.

2

Bạn đã có một số câu trả lời tốt ở đây, tôi muốn giải quyết một câu hỏi vài cụ thể mà bạn có:

Ý tưởng về mô tả các lớp học với giá trị setter và/hoặc các thông số nhà xây dựng dường như xa lạ với tôi. Tại sao vậy? Bởi vì chúng ta có thể thay đổi các thuộc tính mà không biên dịch lại dự án? Đó là tất cả những gì chúng ta đạt được?

Nó có vẻ lạ lúc đầu, nhưng vấn đề là các container là chịu trách nhiệm về cắm vào phụ thuộc cho các đối tượng, các đối tượng chính họ là không chịu trách nhiệm về điều đó. Phạm vi của các đối tượng được cấu hình trong beans.xml được Spring quản lý, vì vậy chúng ta không phải lo lắng nhiều về những thứ được khởi tạo mà không có các phụ thuộc đúng (miễn là cấu hình đúng, tôi đã biết để viết các bài kiểm tra đơn vị để kiểm tra xem cấu hình lò xo có đang làm những gì tôi muốn không.)

Sau đó, chúng ta nên mô tả những đối tượng nào trong beans.xml? Tất cả các đối tượng hoặc chỉ một vài?

Các loại của các đối tượng được mô tả trong beans.xml chủ yếu là các thành phần - bộ điều khiển, dịch vụ, các đối tượng truy cập dữ liệu, và những điều mà họ cần như các nhà quản lý giao dịch, hibernate máy phiên, nguồn dữ liệu, công cụ như thế. Các đối tượng miền thường được truy xuất từ ​​các đối tượng truy cập dữ liệu hoặc được tạo trực tiếp, vì chúng không có phụ thuộc vào bất kỳ thứ gì trừ các đối tượng miền khác (hoặc trên các lớp tiện ích thậm chí độc lập hơn các lớp miền).

1

Có thể bạn không nên cố gắng thực hiện 'phát triển doanh nghiệp Java' mà không có ý tưởng nào về các mối quan tâm về kiến ​​trúc và thiết kế cơ bản? Tôi đề nghị bạn nên tìm một đồng nghiệp có kinh nghiệm sẵn sàng giúp đỡ bạn, hoặc đầu tư thêm một số nỗ lực trong việc đọc những cuốn sách đó, hoặc theo một khóa học khác.

Trong mọi trường hợp, không có câu trả lời đơn giản nào cho câu hỏi của bạn.

0

Tiêm phụ thuộc là giải pháp cho việc thiếu lớp ảo!

 

NB: nếu bạn không biết những gì các lớp học ảo, vui lòng tham khảo "Virtual classes, anyone?".

+1

Sự kinh dị của C++ nhiều thừa kế ảo sẽ ở bên tôi mãi mãi. Tôi thích bài viết đó, nhưng bạn cần một cái tên mới. Giờ đây, các khung công tác DI sử dụng các chú thích để chúng gần như không thể phân biệt được với một tính năng ngôn ngữ - cho đến khi hai khung công tác khác nhau va chạm và ảo tưởng bị tan vỡ. –

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