Autowire class which extends non-container class
I have next structure:
@Component public abstract class
HuginJob extends QuartzJobBean {...}
@Component("CisxJob") public class
CisxJob extends HuginJob {...}
Now I want to test CisxJob:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"/applicationContext-test.xml" })
public class CisxJobTest {
@Autowired
@Qualifier("CisxJob")
private CisxJob cisxJob;
..... }
Here is part of applicationContext-test.xml
<context:annotation-config />
<context:component-scan base-package="no.hugin.jobscheduler" />
Error is
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'no.hugin.jobscheduler.job.cisx.CisxJobTest': Injection of autowired dependencies failed; nested exception is rg.springframework.beans.factory.BeanCreationException: Could not autowire field: private no.hugin.jobscheduler.job.cisx.CisxJob no.hugin.jobscheduler.job.cisx.CisxJobTest.cisxJob; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [no.hugin.jobscheduler.job.cisx.CisxJob] 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), @org.springframework.beans.factory.annotation.Qualifier(value=Cis开发者_C百科xJob)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286) .............
The problem is in extending of QuartzJobBean - but I need it.
Thank you
The problem is in a way Spring generates AOP proxies. When class being proxied implements any interfaces, Spring by default creates a JDK proxy that implement these interfaces.
Since QuartzJobBean
implements an interface Job
, CisxJob
is proxied as Job
, and that proxy can't be autowired to the field of type CisxJob
.
There are two solutions:
If your bean implement any interfaces, create an interface for its business methods as well, and use it as a field type:
public interface CisxJob { ... } @Component("CisxJob") public class CisxJobImpl extends HuginJob implements CisxJob {...}
Use proxy-target-class mode:
<aop:aspectj-autoproxy proxy-target-class = "true" />
See also:
- 7.6 Proxying mechanisms
精彩评论