2012-07-04 19 views
17

Tôi có một rắc rối với Autowire này:mùa xuân dự kiến ​​ít nhất 1 đậu mà đủ điều kiện như autowire ứng cử viên cho sự phụ thuộc này

@Controller 
public class ChiusuraController { 

    @Autowired 
    private ChiusuraProvider chiusuraProvider; 
} 

với đậu này:

@Service @Transactional 
public class ChiusuraProvider extends ThreadProvider { 


    public void run() {} 
} 

kéo dài

public abstract class ThreadProvider extends Thread implements InitializingBean, Runnable, DisposableBean { 
... 
} 

Tôi nhận được lỗi này:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'chiusuraController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cinebot.service.ChiusuraProvider com.cinebot.web.controller.ChiusuraController.chiusuraProvider; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.cinebot.service.ChiusuraProvider] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 

Tôi thấy rằng tôi đã không nhận được lỗi này nếu tôi xóa mở rộng ThreadProvider của lớp tự động, nhưng tôi thực sự cần lớp trừu tượng ThreadProvider.

Trả lời

19

Nếu có giao diện ở bất kỳ đâu trong phân cấp ThreadProvider, hãy thử đặt tên Giao diện làm loại nhà cung cấp dịch vụ của bạn, ví dụ: nếu bạn có nói cấu trúc này:

public class ThreadProvider implements CustomInterface{ 
... 
} 

Sau đó, trong điều khiển của bạn thử điều này:

@Controller 
public class ChiusuraController { 

    @Autowired 
    private CustomInterface chiusuraProvider; 
} 

Lý do tại sao điều này xảy ra là, trong trường hợp đầu tiên của bạn khi bạn không có ChiusuraProvider mở rộng ThreadProvider mùa xuân lẽ đã tạo ra một proxy dựa trên CGLIB cho bạn (để xử lý @Transaction).

Khi bạn DID mở rộng từ ThreadProvider giả sử ThreadProvider mở rộng một số giao diện, Spring trong trường hợp đó tạo Proxy dựa trên proxy động, có vẻ như là triển khai giao diện đó thay vì là loại ChisuraProvider.

Nếu bạn hoàn toàn cần phải sử dụng ChisuraProvider bạn có thể thử AspectJ như một sự thay thế hoặc buộc cglib dựa proxy trong trường hợp với ThreadProvider cũng theo cách này:

<aop:aspectj-autoproxy proxy-target-class="true"/> 

Dưới đây là một số tài liệu tham khảo thêm về điều này từ Reference mùa xuân site: http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/classic-aop-spring.html#classic-aop-pfb

+0

Điều gì sẽ xảy ra nếu lớp của tôi triển khai nhiều giao diện? – user1050619

+0

Đợi ... bạn chỉ cần cứu mạng tôi. Tôi đã sử dụng phiên bản chú thích @EnableAspectJAutoProxy (proxyTargetClass = true). Cảm ơn bạn! –

7

Bạn nên đặt dòng này trong bối cảnh ứng dụng của bạn:

<context:component-scan base-package="com.cinebot.service" /> 

Read more about Automatically detecting classes and registering bean definitions in documentation.

+0

Tôi đã thêm dòng này trong đó ChiusuraProvider được bao gồm trong gói com.cinebot.service và ThreadProvider KHÔNG được bao gồm trong gói đó ... nhưng nó không hoạt động. – Tobia

+0

Bạn đã thử câu trả lời của @ BijuKunjummen (sử dụng proxy có phạm vi AOP, hãy nhớ thêm phụ thuộc CGLIB)? – Xaerxess

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