解决spring问题(Unsatisfied dependency)的意外发现

前几天在做一个Dao的单元测试的时候,碰到了一个spring的错误。如下:

[quote]org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'my.demo.dao.UUIDClassDaoTest': Unsatisfied dependency expressed through bean property 'UUIDClassDao': Set this property value or disable dependency checking for this bean.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
.checkDependencies(AbstractAutowireCapableBeanFactory.java:1019)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.
populateBean(AbstractAutowireCapableBeanFactory.java:839)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.
autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:273)
at org.springframework.test.AbstractDependencyInjectionSpringContextTests.
injectDependencies(AbstractDependencyInjectionSpringContextTests.java:179)
at org.springframework.test.AbstractDependencyInjectionSpringContextTests.
prepareTestInstance(AbstractDependencyInjectionSpringContextTests.java:158)
at org.springframework.test.AbstractSingleSpringContextTests.setUp(Abstrac
tSingleSpringContextTests.java:88)
at junit.framework.TestCase.runBare(TestCase.java:128)[/quote]

我的Dao单元测试类继承自 AbstractTransactionalDataSourceSpringContextTests
这个类,它可以提供对springContext的支持。

从errorstack中看,好像是Dao中的属性没有设置好。 所以, 我检查了代码,Dao中 定义了属性 uUIDClassDao,并且提供了set方法,如下:
[code] private UUIDClassDao uUIDClassDao = null;
public void setUUIDClassDao(UUIDClassDao uUIDClassDao) {
this.uUIDClassDao = uUIDClassDao;
} [/code]

在Spring context文件中,定义了如下的bean。

[code] <bean id="uUIDClassDao" class="my.demo.dao.hibernate.UUIDClassDaoHibernate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean> [/code]

看起来没问题呀,bean的id和dao中定义的属性都是 uUIDClassDao,通过把autowire模式设置成 AUTOWIRE_BY_NAME ,应该我的dao测试类会被自动注入uUIDClassDao这个bean的。

可是很意外,这并没有发生。What’s the problem ?

我又仔细看了看error stack,忽然发现,提示的是 “Unsatisfied dependency expressed through bean property '[b]UUIDClassDao[/b]':”。注意,不是uUIDClassDao,而是UUIDClassDao。

难道Spring会把uUIDClassDao识别成 UUIDClassDao ?
我跟踪了spring的代码,发现,spring在拿到单元测试dao的时候,用了Introspector.getBeanInfo(Class class0) 去得到对象的属性。的的确确,通过这种方式拿到的属性名是 UUIDClassDao,而不是uUIDClassDao。

为了再次验证,我写了一个简单的测试程序:

[code]import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;


public class AppBeanInfo {

/**
* @param args
*/
public static void main(String[] args) throws Exception {

BeanInfo info = Introspector.getBeanInfo(MyReflection.class);
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
System.out.println(pd.getName());
}
BeanInfo info2 = Introspector.getBeanInfo(MyReflection2.class);
for (PropertyDescriptor pd : info2.getPropertyDescriptors()) {
System.out.println(pd.getName());
}
}

}

public class MyReflection {
String mRef;

public String getMRef() {
return mRef;
}

public void setMRef(String ref) {
mRef = ref;
}

}


public class MyReflection2 {
String mmRef;

public String getMmRef() {
return mmRef;
}

public void setMmRef(String mmRef) {
this.mmRef = mmRef;
}

}
[/code]

输出结果是
MRef
class
class
mmRef
也就是对mRef这种字段,用自省识别出来的属性名竟然是MRef。

so, 在程序中尽量不要定义 uUIDClassDao这种属性,而用uuidClassDao。因为可能在你不知道的地方,uUIDClassDao已经被识别成了 UUIDClassDao。
Spring框架中,`UnsatisfiedDependencyException`通常表示应用无法满足某个依赖注入(DI)的需求。这是因为Spring试图在运行时创建一个bean实例,但找不到合适提供者或配置。以下是几种常见的处理方法: 1. **检查装配注解**:确保所有需要注入的类、接口或方法都正确地使用了@Autowired、@Qualifier、@Resource等装配注解。 2. **检查@Component或@Service声明**:如果你正在为类或接口定义一个bean,确保它们已经被正确的标签标记,如@Component或@Service,并且没有遗漏任何必需的属性。 3. **检查配置文件**:检查applicationContext.xml或者application.yml(对于Spring Boot)中的bean定义是否完整和正确。特别是检查bean id、scope、构造函数参数以及依赖之间的关系。 4. **查找依赖冲突**:如果有多个bean匹配同一个类型,确保有一个明确的qualifier或者自定义bean名称来区分它们。 5. **检查生命周期管理**:如果依赖关系涉及不同生命周期的bean(例如,父bean依赖于子bean),确保生命周期顺序正确。 6. **查看日志信息**:Spring会生成详细的错误消息,包括导致异常的具体原因,这有助于定位问题。 7. **使用Spring Tool Suite或IntelliJ IDEA等IDE插件**:这些工具可以帮助检测并修复潜在的问题。 如果以上步骤都无法解决问题,你可能需要分析具体的异常堆栈跟踪,并查看Spring Boot Actuator提供的endpoints,如`beans` endpoint,以便获取更深入的诊断信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值