从Quick Start的例子中可以看到,所谓依赖注入,即在运行期由容器将依赖关系注入到组件之中。
讲的通俗点,就是在运行期,由Spring根据配置文件,将其他对象的引用通过组件的提供的setter方法进
行设定。
我们知道,如果动态设置一个对象属性,可以借助Java的Reflection机制完成:
Class cls = Class.forName("net.xiaxin.beans.User");
Method mtd = cls.getMethod("setName",new Class[]{String.class});
Object obj = (Object)cls.newInstance();
mtd.invoke(obj,new Object[]{"Erica"});
return obj;
上面我们通过动态加载了User类,并通过Reflection调用了User .setName方法设置其name属性。
对于这里的例子而言,出于简洁,我们将类名和方法名都以常量的方式硬编码。假设这些常量都是通过配
置文件读入,那我们就实现了一个最简单的BeanWrapper。这个BeanWrapper的功能很简单,提供一个
设置JavaBean属性的通用方法(Apache BeanUtils 类库中提供了大量针对Bean的辅助工具,如果有兴
趣可以下载一份源码加以研读) 。
Spring BeanWrapper基于同样的原理,提供了一个更加完善的实现。
看看如何通过Spring BeanWrapper操作一个JavaBean:
Object obj = Class.forName("net.xiaxin.beans.User").newInstance();
BeanWrapper bw = new BeanWrapperImpl(obj);
bw.setPropertyValue("name", "Erica");
System.out.println("User name=>"+bw.getPropertyValue("name"));
对比之前的代码,相信大家已经知道BeanWrapper的实现原理。
诚然,通过这样的方式设定Java Bean属性实在繁琐,但它却提供了一个通用的属性设定机制,而这
样的机制,也正是Spring依赖注入机制所依赖的基础。
通过BeanWrapper,我们可以无需在编码时就指定JavaBean的实现类和属性值,通过在配置文件
加以设定,就可以在运行期动态创建对象并设定其属性(依赖关系) 。
上面的代码中,我们仅仅指定了需要设置的属性名“name”,运行期,BeanWrapper将根据Java
Bean规范,动态调用对象的“setName”方法进行属性设定。属性名可包含层次,如对于属性名
“address.zipcode”,BeanWrapper会调用“getAddress().setZipcode”方法。