论坛首页 Java企业应用论坛

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

浏览 9994 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-06-19  
前几天在做一个Dao的单元测试的时候,碰到了一个spring的错误。如下:

引用
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)


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

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


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

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


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

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

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

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

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

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;
	}
	
}


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

so, 在程序中尽量不要定义 uUIDClassDao这种属性,而用uuidClassDao。因为可能在你不知道的地方,uUIDClassDao已经被识别成了 UUIDClassDao。

   发表时间:2007-06-19  
这是javabean规范的一部分,用于处理缩写等情况。建议可以去看看java.beans.Introspector decapitalize的源代码
0 请登录后投票
   发表时间:2007-06-19  
注意下规范就行了,很多框架都是默认的按照首字母大写来做的!
0 请登录后投票
   发表时间:2007-06-19  
decapitalize是一个静态方法,将一个字符串的首字母从大写变成小写。
getBeanInfo调用了几次这个方法,但是好像和我说的不完全是一件事情呢。下面是这个方法的说明。

Utility method to take a string and convert it to normal Java variable name capitalization. This normally means converting the first character from upper case to lower case, but in the (unusual) special case when there is more than one character and both the first and second characters are upper case, we leave it alone.

Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays as "URL".

0 请登录后投票
   发表时间:2007-06-19  
galaxystar 写道
注意下规范就行了,很多框架都是默认的按照首字母大写来做的!


之前确实不知道java会把一个mRef的field,识别成MRef的属性。
0 请登录后投票
   发表时间:2007-06-19  
连续两个帖子发现这种JavaBean的规范问题,还套了那么大一个标题。

难道不会搜索一下吗?
0 请登录后投票
   发表时间:2007-06-19  
downpour 写道
连续两个帖子发现这种JavaBean的规范问题,还套了那么大一个标题。

难道不会搜索一下吗?


拜托看清楚帖子再说话。

我拿unsatisfied dependency在论坛中搜了,没有相近的问题。
问题的关键是,我一开始并不清楚这问题和javabean规范有关。

而且并不是所有javaeyer都像你那么牛,每个规范都那么熟。

发这个帖子,只是希望今后有朋友碰到相近的问题,用 Unsatified dependency搜索,还能发现原来是javabean规范导致的问题。

如果大家觉得没有帮助,可以把这个帖子投成隐藏帖。让其只存放在blog中。
0 请登录后投票
   发表时间:2007-06-20  
以前也遇到过这种问题,总算知道是为什么了,谢谢楼主!
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics