Spring 大量引入了 Java 的 Reflection 机制,通过动态 所谓依赖注入,即在运行期由容器将依赖关系注入到组件之中。 上面我们通过动态加载了User类,并通过Reflection调用了User.setName方法设置其name属性。 Spring BeanWrapper基于同样的原理,提供了一个更加完善的实现。 对比之前的代码,相信大家已经知道BeanWrapper的实现原理。 Bean Factory,顾名思义,负责创建并维护Bean实例。 联合上面关于BeanWrapper的内容,我们可以看到,BeanWrapper实现了针对单个Bean的属性设 BeanFactory提供了针对Java Bean的管理功能,而ApplicationContext提供了一个更为框架化的 BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;ApplicationContext 面向使用Spring 框架的开发者,几乎所有的应用场合我们都直接使用 ApplicationContext 而非底层的 BeanFactory。 http://www.kaiyuanba.cn/content/develop/SpringGuide.pdf
调用的方式避免硬编码方式的约束,并在此基础上建立了其核心组件 BeanFactory,以此作为其依赖注入
机制的实现基础。
org.springframework.beans 包中包括了这些核心组件的实现类,核心中的核心为 BeanWrapper
和 BeanFactory 类。这两个类从技术角度而言并不复杂,但对于 Spring 框架而言,却是关键所在,如果
有时间,建议对其源码进行研读,必有所获。Bean Wrapper
讲的通俗点,就是在运行期,由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;
对于这里的例子而言,出于简洁,我们将类名和方法名都以常量的方式硬编码。假设这些常量都是通过配
置文件读入,那我们就实现了一个最简单的BeanWrapper。这个BeanWrapper的功能很简单,提供一个
设置JavaBean属性的通用方法(Apache BeanUtils 类库中提供了大量针对Bean的辅助工具,如果有兴
趣可以下载一份源码加以研读)。
看看如何通过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"));
诚然,通过这样的方式设定Java Bean属性实在繁琐,但它却提供了一个通用的属性设定机制,而这
样的机制,也正是Spring依赖注入机制所依赖的基础。
通过BeanWrapper,我们可以无需在编码时就指定JavaBean的实现类和属性值,通过在配置文件
加以设定,就可以在运行期动态创建对象并设定其属性(依赖关系)。
上面的代码中,我们仅仅指定了需要设置的属性名“name”,运行期,BeanWrapper将根据Java
Bean规范,动态调用对象的“setName”方法进行属性设定。属性名可包含层次,如对于属性名“address.zipcode”,BeanWrapper会调用“getAddress().setZipcode”方法。Bean Factory
Bean Factory负责根据配置文件创建Bean实例,可以配置的项目有:
1. Bean属性值及依赖关系(对其他Bean的引用)
2. Bean创建模式(是否Singleton模式,即是否只针对指定类维持全局唯一的实例)
3. Bean初始化和销毁方法
4. Bean的依赖关系
定操作。而BeanFactory则是针对多个Bean的管理容器,根据给定的配置文件,BeanFactory从中读取
类名、属性名/值,然后通过Reflection机制进行Bean加载和属性设定。ApplicationContext
实现(从上面的示例中可以看出,BeanFactory的使用方式更加类似一个API,而非Framework style)。
ApplicationContext覆盖了BeanFactory的所有功能,并提供了更多的特性。此外,
ApplicationContext为与现有应用框架相整合,提供了更为开放式的实现(如对于Web应用,我们可以在
web.xml中对ApplicationContext进行配置)。
相对BeanFactory而言,ApplicationContext提供了以下扩展功能:
我们可以在Beans.xml文件中,对程序中的语言信息(如提示信息)进行定义,将程序中的提示
信息抽取到配置文件中加以定义,为我们进行应用的各语言版本转换提供了极大的灵活性。
支持对文件和URL的访问。
事件传播特性为系统中状态改变时的检测提供了良好支持。
可以在同一个应用中加载多个Context实例。小结
参考