2010-04-23 32 views
15

tôi có 2 lớp (B, C) kéo dài lớp A.Vấn đề với Autowiring & Không đậu độc đáo

@Service 
public class A extends AbstratClass<Modele>{ 

    @Autowired 
    A(MyClass br) { 
     super(br); 
    } 


@Service 
public class B extends A{ 

    @Autowired 
    B (MyClass br) { 
    super(br); 
    } 



@Service 
public class C extends A{ 

    @Autowired 
    C (MyClass br) { 
    super(br); 
    } 

Nhưng tôi có tin nhắn này:

Không đậu độc đáo của loại [A] ] được định nghĩa: dự kiến ​​đơn đậu khớp nhưng thấy 2: [A, B, moveModeleMarshaller]

tôi thực sự không thể hiểu tại sao tôi có thông điệp này & làm thế nào để giải quyết ngay cả sau khi đọc xuân documentatio n.

Xin cảm ơn trước.

+0

tôi cũng đang nhận được cùng một vấn đề nhưng không thể tìm thấy phù hợp giải pháp xin hãy giúp tôi ... cảm ơn bạn –

Trả lời

4

Bạn đang cố gắng (ở một nơi khác) để tự động lấy một loại đậu A. Một cái gì đó như:

@Autowired 
private A beanA; 

Nhưng bạn có 2 loại đậu phù hợp với điều này.

Bạn có thể giải quyết điều này bằng cách sử dụng @Resource và đó nêu rõ đậu chính xác:

@Resource("b") 
private A beanA; 

(nơi "b" là tên của bean tiêm) hoặc sử dụng @Qualifier chú thích.

14

Bạn nên viết lại lớp học của mình thành một thứ như thế này với chú thích @Qualifier.

@Service 
@Qualifier("a") 
public class A extends AbstratClass<Modele>{ 

    @Autowired 
    A(MyClass br) { 
     super(br); 
    } 


@Service 
@Qualifier("b") 
public class B extends A{ 

    @Autowired 
    B (MyClass br) { 
    super(br); 
    } 

@Service 
@Qualifier("c") 
public class C extends A{ 

    @Autowired 
    C (MyClass br) { 
    super(br); 
    } 

Bạn cũng phải sử dụng chú thích @Qualifier trên cá thể loại A mà bạn đang tự động điền bean Spring vào.

Something như thế này:

public class Demo { 

    @Autowired 
    @Qualifier("a") 
    private A a; 

    @Autowired 
    @Qualifier("b") 
    private A a2; 

    public void demo(..) {..} 
} 

Nếu bạn không muốn có cấu hình Spring này trong mã sản xuất của bạn, bạn phải viết logic dependency injection với XML hoặc cấu hình Java để thay thế.

Bạn cũng có thể chỉ định bean mặc định loại A với chú thích @Primary ở trên một trong các lớp dịch vụ mở rộng loại A. Sau đó, Spring có thể tự động xác định chú thích @Qualifier.

Vì mùa xuân sẽ không bao giờ cố gắng đoán hạt nào cần tiêm, bạn phải chỉ định cái nào hoặc đánh dấu một trong số chúng với @Primary miễn là nhiều hơn một loại đậu.

+1

một ý kiến ​​cá nhân - Tôi thích '@ Tài nguyên' cho các trường hợp đơn giản hơn. – Bozho

+0

Đó chỉ là chi tiết nhỏ, nhưng tôi thích sử dụng chú thích @Autowired hoặc new @Inject (JSR-330) trong mọi trường hợp. Một nhược điểm có thể xảy ra với @Resource và @Inject là bạn không có chúng trên classpath vì nó không phải là một phần của Spring. – Espen

2

Nói chung, bạn sẽ nhận được lỗi này khi định nghĩa hai đậu với cùng một lớp

<bean id="a" class="com.package.MyClass"/> 
<bean id="b" class="com.package.MyClass"/> 

nếu bạn giải quyết hai dòng ở trên chúng ta có hai đậu với cùng một lớp.

khi bạn cố gắng để autowire lớp này trong bất kỳ khác xếp vào loại bạn sẽ nhận được loại hình này lỗi

Bạn có hai giải pháp

Đầu tiên Phương pháp

  1. sử dụng vòng loại bằng cách định nghĩa một id đậu init như thế này

    @Autowired 
    @Qualifier("a") 
    MyClass a; 
    
    @Autowired 
    @Qualifier("b") 
    MyClass b; 
    

Phương pháp thứ hai

sử dụng JSR250 api (một file jar của nó bạn có thể đưa vào đường dẫn lớp của bạn

Sau đó làm autowriring như dưới đây

@Resource("a") 
MyClass a 

@Resource("b") 
MyClass a 
Các vấn đề liên quan