[转载]详细讲解在Spring中进行集成测试五(解决自动装配问题 )

解决自动装配问题
如果Spring容器中拥有多个匹配UserService类型的Bean,由于Spring没有足够的信息做出取舍决策,因此会抛出 UnsatisfiedDependencyException异常。假设我们采用以下传统的事务管理的配置方式对UserService进行配置,按类 型匹配的自动装配机制就会引发问题:
①用于被代理的目标Bean,按类型匹配于UserService
<bean id="userServiceTarget" class="com.baobaotao.service.UserServiceImpl">
<property name="userDao" ref="userDao" />
<property name="loginLogDao" ref="loginLogDao">property>
bean>
②通过事务代理工厂为UserServiceImpl创建的代理Bean,也按匹配于UserService
<bean id="userService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager" />
<property name="target" ref="userServiceTarget" />
<property name="transactionAttributes">

property>
bean>
由于①处和②处的Bean都按类型匹配于UserService,在对DependencyInjectionCtxTest的userService属性进行自动装配将会引发问题。有两种针对该问题的解决办法:
 调整配置文件,使按类型匹配于UserService的Bean仅有一个,具体有以下两个方法:

 将①处的Bean作为②处的内部Bean进行装配;

 使用基于注解驱动的事务管理配置机制,这样就无需在配置文件中定义两个UserService的Bean了。关于注解驱动事务管理配置的详细信息,请参见9.6小节的内容。

 改变DependencyInjectionCtxTest的自动装配机制:Spring默认使用byType类型的自动装配机制,但它允许你通过 setAutowireMode()的方法改变默认自动装配的机制,比如你可以调用setAutowireMode(AUTOWIRE_BY_NAME) 方法启用按名称匹配的自动装配机制。AbstractDependencyInjectionSpringContextTests定义了三个代表自动装 配机制类型的常量,分别说明如下:
 AUTOWIRE_BY_TYPE:按类型匹配的方式进行自动装配,这个默认的机制;
 AUTOWIRE_BY_NAME:按名字匹配的方式进行自动装配
 AUTOWIRE_NO:不使用自动装配机制,这意味着你需要手工调用getBean()进行装配。

现在我们解决了在自动装配时,因Spring容器中存在多个匹配Bean而导致的问题,接下来让我们考察另一个自动装配的问题。
依赖检查
假设我们在DependencyInjectionCtxTest添加一个User类型的属性并提供Setter方法,而Spring容器中没有匹配该属性的Bean:
package com.baobaotao.test;

import com.baobaotao.domain.User;
public class DependencyInjectionCtxTest extends AbstractDependencyInjectionSpringContextTests {
private User user;
public void setUser(User user) {
this.user = user;
}

}
猜想一下重新运行DependencyInjectionCtxTest将会发生什么情况呢?答案可能让你失望: UnsatisfiedDependencyException再次象黑幕一样降临。在默认情况下, AbstractDependencyInjectionSpringContextTests要求所有属性都能在Spring容器中找到对应Bean, 否则抛出异常。
仔细思考一下,这种运行机制并非没有道理,因为既然你已经提供了Setter方法,就相当于给出了这样的暗示信息: “这个属性测试类自身创建不了,必须由外部提供”。而在使用自动装配机制的情况下,测试类属性自动从Spring容器中注入匹配的属性,一般情况下不会手 工去调用Setter方法准备属性。
如果你出于一些特殊的理由,希望在采用自动装配的情况下,如果有属性未得到装配也不在乎,那么你可以在测试类构造函数中调用setDependencyCheck(false)方法达到目的:
package com.baobaotao.test;

public class DependencyInjectionCtxTest extends AbstractDependencyInjectionSpringContextTests {
public DependencyInjectionCtxTest(){
setDependencyCheck(
false); ①告知不进行属性依赖性检查
}

}
这个AbstractDependencyInjectionSpringContextTests就不会对测试类有些属性找不到匹配Bean而抛出异常了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值