我有以下课程: com.foo.pkgx:
@Component public class A {}
@Component public class B {
@Autowired A a;
}
com.foo.pkgy:
@Component public class C {
@Autowired B b;
}
I.E。依赖关系:C-> B-> A
执行以下spock规范时:
@Configuration
@ComponentScan(basePackages = ["com.foo.pkgy"])
class Config {
def mockFactory = new DetachedMockFactory()
@Bean
B b() {mockFactory.Mock(B)};
}
@ContextConfiguration(classes = Config)
class CSpec extends Specification {
@Autowired
C c;
def "sanity"() {
expect: c
}
}
测试未能初始化:
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'c':
Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: com.foo.pkgx.B com.foo.pkgy.C.b;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'b':
Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: com.foo.pkgx.A com.foo.pkgx.B.a;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.foo.pkgx.A] 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)}
我将其读为“试图将A连接到B,但失败了”。我没想到B会被自动装配,因为它被嘲笑了。
有人可以给我一些启示吗?
谢谢!
答案 0 :(得分:1)
类的模拟是由代码生成库,字节伙伴或cglib-nodep等生成的子类。从Spring的角度来看,这是一个普通的bean。并且一旦实例化了任何bean,然后在某个时候,Spring就会通过各种...BeanPostProcessors
来对bean进行“自省”。例如。自动装配由AutowiredAnnotationBeanPostProcessor
处理。该后处理器的工作方式是,整个类层次结构中的每个bean都是inspected。因此,您的class B
和@Autowired
字段A
在那里,Spring尝试解决这种依赖关系时没有运气。
然而,好消息是,需要禁用每个bean的自动装配功能。最终看起来像Spring团队will introduce it soon。
与此同时,您可以模拟A
,以便解决B
的依赖性。或者,您可以只为组件使用接口,而不是仅使用类。我相信后者是最佳实践