解決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。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章