Spring: Tại sao chúng ta tự động giao diện mà không phải lớp triển khai?


142

Thí dụ

interface IA
{
  public void someFunction();
}

@Resource(name="b")
class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}

@Resource(name="c")
class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

class MyRunner
{

  @Autowire
  @Qualifier("b") 
  IA worker;

  worker.someFunction();
}

Ai đó có thể giải thích điều này với tôi.

  • Làm thế nào để mùa xuân biết loại đa hình để sử dụng.
  • Tôi có cần @Qualifierhay @Resourcekhông?
  • Tại sao chúng ta tự động giao diện mà không phải lớp thực hiện?

10
Bạn tự động cài đặt giao diện để bạn có thể kết nối một cách triển khai khác - đó là một trong những điểm mã hóa cho giao diện, không phải lớp.
Dave Newton

Bạn muốn thực hiện một cách khác nhau; Tôi không hiểu câu hỏi.
Dave Newton

Nếu chúng ta đang nối dây trong giao diện, điều gì xảy ra khi có một phương thức hiển thị mặc định trong lớp Impl mà tôi cần truy cập? Tôi không thể thêm sơ khai phương thức đó vào giao diện vì Giao diện công cộng không thể chứa công cụ sửa đổi mặc định.
jlewkovich


1
Tôi nghĩ rằng việc tạo một giao diện cho chỉ một lần thực hiện là một cách thực hành ngu ngốc được chấp nhận trong thế giới java. Kết quả là có rất nhiều mã rác, nhưng mọi người đều vui khi họ tuân theo các quy tắc của RẮN và OOP. Sử dụng guice và ném mùa xuân vào thùng rác của lịch sử.
avgolubev

Câu trả lời:


224

Làm thế nào để mùa xuân biết loại đa hình để sử dụng.

Miễn là chỉ có một triển khai duy nhất của giao diện và việc triển khai đó được chú thích với chức @Componentnăng quét thành phần của Spring được kích hoạt, Spring framework có thể tìm ra cặp (giao diện, triển khai). Nếu quét thành phần không được bật, thì bạn phải xác định rõ ràng bean trong application-config.xml (hoặc tệp cấu hình lò xo tương đương).

Tôi có cần @Qualifier hoặc @Resource không?

Khi bạn có nhiều hơn một lần triển khai, thì bạn cần phải đủ điều kiện cho mỗi lần thực hiện và trong quá trình tự động nối dây, bạn sẽ cần sử dụng @Qualifierchú thích để thực hiện đúng việc thực hiện, cùng với @Autowiredchú thích. Nếu bạn đang sử dụng @Resource (ngữ nghĩa J2EE), thì bạn nên chỉ định tên bean bằng namethuộc tính của chú thích này.

Tại sao chúng ta tự động giao diện mà không phải lớp thực hiện?

Thứ nhất, luôn luôn là một thực hành tốt để mã hóa các giao diện nói chung. Thứ hai, trong trường hợp mùa xuân, bạn có thể thực hiện bất kỳ thực hiện nào trong thời gian chạy. Một trường hợp sử dụng điển hình là tiêm thực hiện giả trong giai đoạn thử nghiệm.

interface IA
{
  public void someFunction();
}


class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}


class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

class MyRunner
{
     @Autowire
     @Qualifier("b") 
     IA worker;

     ....
     worker.someFunction();
}

Cấu hình bean của bạn sẽ trông như thế này:

<bean id="b" class="B" />
<bean id="c" class="C" />
<bean id="runner" class="MyRunner" />

Ngoài ra, nếu bạn kích hoạt quét thành phần trên gói có các gói này, thì bạn nên đủ điều kiện cho mỗi lớp @Componentnhư sau:

interface IA
{
  public void someFunction();
}

@Component(value="b")
class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}


@Component(value="c")
class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

@Component    
class MyRunner
{
     @Autowire
     @Qualifier("b") 
     IA worker;

     ....
     worker.someFunction();
}

Sau đó, workertrong MyRunnersẽ được tiêm với một thể hiện của loại B.


@stackoverflow Chỉnh sửa câu hỏi sẽ không có ý nghĩa gì, mã mới thuộc về câu trả lời. Nếu không, câu hỏi không có ý nghĩa, bởi vì nó sẽ tự trả lời.
Dave Newton

Vikdor - vui lòng xem chỉnh sửa. Đó có phải là cách chính xác để chú thích các lớp và đối tượng được tiêm?
stackoverflow

1
@VictorDombrovsky Có @Autowired @Qualifier("a1") a;hợp lệ không?
May mắn

1
@Lucky tôi đã làm sai. Ý tôi là@Autowired @Qualifier("a1") A a;
Victor Dombrovsky

1
Thậm chí, bạn có thể sử dụng @Profile trong quá trình triển khai để kiểm soát việc triển khai nào nên được chèn cho giao diện đó thông qua các đối số chương trình hoặc thuộc tính ứng dụng.
b15

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.