我对春天的DI感到困惑
public interface C{
void methodC();
}
public class CAutowired implements C{
@Autowired
private A a;
@Autowired
private B b;
public void methodC(){
a.methodA();
b.methodB();
}
}
我有两个接口A和B,2个类实现它。 所以,我有2个实现接口C的类,它依赖于接口A和B
这是案例1:
<beans>
<bean id="classA" class="com.example.AImpl" />
<bean id="classB" class="com.example.BImpl" />
<bean id="classC" class="com.example.CAutowired" />
<beans>
档案.xml配置
public class CInitInject implements C{
private A a;
private B b;
public CInitInject(A a, B b){
this.a = a;
this.b = b;
}
public void methodC(){
a.methodA();
b.methodB();
}
}
在这种情况下,我有一个问题: - 当我为类CATowowired编写unitTest时如何模拟A和B
这是案例2:
<beans>
<bean id="classA" class="com.example.AImpl" />
<bean id="classB" class="com.example.BImpl" />
<bean id="classC" class="com.example.CInitInject">
<constructor-arg ref="classA" />
<constructor-arg ref="classB" />
</bean>
<beans>
档案.xml配置
@Mock
private A aMock;
@Mock
private B bMock;
private C c;
public void setUp(){
c = new CInitInject(aMock, bMock);
}
@Test
public void test(){
// todo Test somemethod
}
在这种情况下,我在.NET中获得相同的DI方法。我可以注射模拟A和B. 进入构造函数。例如:
{{1}}
最后,我有一个问题
答案 0 :(得分:0)
<强>(1)强>
现在习惯将bean注入构造函数。
它被认为是最佳实践,因为它严格通知类的用户(在本例中为CInitInject
的用户)对此类的期望是什么,以使其正常工作。用户不必猜测setter会发生哪些依赖项。
<强>(1.1)强>
“案例1”的代码示例捆绑了两种代码样式,您可能希望避免这种情况。
在注释驱动编码和XML之间选择是很常见的。
对于这种情况,如果您选择使用注释,您的代码将看起来像这样(注意不涉及XML):
public interface C{
void methodC();
}
@Bean(name="a")
public class AImpl implements A{
public void methodA(){
// todo something
}
}
@Bean
public class CAutowired implements C{
@Autowired
private A a;
@Autowired
private B b;
public void methodC(){
a.methodA();
b.methodB();
}
}
请参阅example了解如何使用帮助代码来完成这项工作。
<强>(1.2)强>
如果你选择使用注释驱动的编码,这里是一个将bean注入构造函数的例子:
@Bean
public class CAutowired implements C {
private A a;
private B b;
@Autowired
public CAutowired(A a, B b) {
this.a = a;
this.b = b;
}
}
<强>(1.3)强>
在使用注释时,避免将Spring硬连接到系统中也很常见。因此,有些人创建的类可以识别spring和其他类(例如CAutowired
,现在将重命名为CImpl
),只有他们使用@Autowired
和@Bean
注释。
例如:
//just an example, you'll think of how this works for YOU
public class OneOfSomeSpringManagers {
public OneOfSomeSpringManagers() {
C c = getC(getA());
}
@Bean
public A getA() {
...
}
...
}
<强>(2)强>