package net.sg.spring;
public interface Action { public String execute(); }
package net.sg.spring.service;
import net.sg.spring.Action;
public class UpperAction implements Action {
private String msg;
public String getMsg() { return msg; }
public void setMsg(String msg) { this.msg = msg; }
public String execute() { return (msg.toUpperCase()); } }
我们知道,如果动态设置一个对象属性,可以借助Java的Reflection机制完成:
try {
Class cls = Class.forName("net.sg.spring.service.UpperAction");
Object obj = cls.newInstance();
Method method = cls.getMethod("setMsg", new Class[]{String.class});
method.invoke(obj, new Object[]{"hello"});
System.out.println(((UpperAction) obj).execute());
}
catch (Exception e)
{System.out.println(e.getStackTrace());}
对于这里的例子而言,出于简洁,我们将类名和方法名都以常量的方式硬编码。假设这些常量都是通过配置文件读入,那我们就实现了一个最简单的BeanWrapper。这个BeanWrapper的功能很简单,提供一个设置JavaBean属性的通用方法(Apache BeanUtils 类库中提供了大量针对Bean的辅助工具,如果有兴趣可以下载一份源码加以研读)。
try {
Class cls = Class.forName("net.sg.spring.service.UpperAction");
Object obj = cls.newInstance();
BeanWrapper beanWrapper = new BeanWrapperImpl(obj);
beanWrapper.setPropertyValue("msg","hello");
System.out.println(beanWrapper.getPropertyValue("msg"));
System.out.println(((UpperAction)obj).getMsg()); }
catch (Exception e) {
System.out.println(e.getStackTrace());
}
通过BeanWrapper,我们可以无需在编码时就指定JavaBean的实现类和属性值,通过在配置文件加以设定,就可以在运行期动态创建对象并设定其属性(依赖关系)。
Bean Factory,顾名思义,负责创建并维护Bean实例。 Bean Factory负责根据配置文件创建Bean实例,可以配置的项目有:
1. Bean属性值及依赖关系(对其他Bean的引用)
2. Bean创建模式(是否Singleton模式,即是否只针对指定类维持全局唯一的实例)
3. Bean初始化和销毁方法
4. Bean的依赖关系
下面的代码演示了如何通过BeanFactory获取Bean实例:
InputStream is = new FileInputStream("bean.xml");
XmlBeanFactory factory = new XmlBeanFactory(is);
Action action = (Action) factory.getBean("uaction");
此时我们获得的Action实例,由BeanFactory进行加载,并根据配置文件进行了初始化和属性设定。联合上面关于BeanWrapper的内容,我们可以看到,BeanWrapper实现了针对单个Bean的属性设定操作。而BeanFactory则是针对多个Bean的管理容器,根据给定的配置文件,BeanFactory从中读取类名、属性名/值,然后通过Reflection机制进行Bean加载和属性设定。
BeanFactory提供了针对Java Bean的管理功能,而ApplicationContext提供了一个更为框架化的实现(从上面的示例中可以看出,BeanFactory的使用方式更加类似一个API,而非Framework style)。ApplicationContext覆盖了BeanFactory的所有功能,并提供了更多的特性。此外,ApplicationContext为与现有应用框架相整合,提供了更为开放式的实现(如对于Web应用,我们可以在web.xml中对ApplicationContext进行配置)。
相对BeanFactory而言,ApplicationContext提供了以下扩展功能:
1. 国际化支持我们可以在Beans.xml文件中,对程序中的语言信息(如提示信息)进行定义,将程序中的提示信息抽取到配置文件中加以定义,为我们进行应用的各语言版本转换提供了极大的灵活性。
2. 资源访问支持对文件和URL的访问。
3. 事件传播事件传播特性为系统中状态改变时的检测提供了良好支持。
4. 多实例加载可以在同一个应用中加载多个Context实例。