Spring 从核心而言,是一个DI 容器,其设计哲学是提供一种无侵入式的高扩展性框架。即无需代码中涉及Spring专有类,即可将其纳入Spring容器进行管理。
作为对比,EJB则是一种高度侵入性的框架规范,它制定了众多的接口和编码规范,要求实现者必须遵从。侵入性的后果就是,一旦系统基于侵入性框架设计开发,那么之后任何脱离这个框架的企图都将付出极大的代价。
为了避免这种情况,实现无侵入性的目标。Spring 大量引入了Java 的Reflection机制,通过动态调用的方式避免硬编码方式的约束,并在此基础上建立了其核心组件BeanFactory,以此作为其依赖注入机制的实现基础。
org.springframework.beans包中包括了这些核心组件的实现类,核心中的核心为BeanWrapper和BeanFactory类。这两个类从技术角度而言并不复杂,但对于Spring 框架而言,却是关键所在,如果有时间,建议对其源码进行研读,必有所获。
(1)BeanWrapper
Spring中的核心接口:通过配置文件中的设定,java Bean就可以在运行期动态创建对象并设定其属性(依赖关系)。
(2)BeanFactory
Bean Factory,顾名思义,负责创建并维护Bean实例
Bean Factory负责根据配置文件创建Bean实例,可以配置的项目有:
<1>. Bean属性值及依赖关系(对其他Bean的引用)
<2>. Bean创建模式(是否Singleton模式,即是否只针对指定类维持全局唯一的实例)
<3>. Bean初始化和销毁方法
<4>. Bean的依赖关系
联合上面关于BeanWrapper的内容,我们可以看到,BeanWrapper实现了针对单个Bean的属性设定操作。而BeanFactory则是针对多个Bean的管理容器,根据给定的配置文件,BeanFactory从中读取类名、属性名/值,然后通过Reflection机制进行Bean加载和属性设定。
在Spring中,BeanFactory是IOC容器的核心接口。它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
(3)ApplicationContext
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实例。
(4)Web Context
对于Web应用,Spring提供了可配置的Application Context加载机制。
加载器目前有两种选择:ContextLoaderListener和ContextLoaderServlet。这两者在功能上完全等同,只是一个是基于Servlet2.3版本中新引入的Listener接口实现,而另一个基于Servlet接口实现。
开发中可根据目标Web容器的实际情况进行选择。
配置非常简单,在web.xml中增加:
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> 或: <servlet> <servlet-name>context</servlet-name> <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> |
通过以上配置,Web容器会自动加载/WEB-INF/applicationContext.xml初始化Application Context实例,如果需要指定配置文件位置,可通过context-param加以指定:
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/myApplicationContext.xml</param-value> </context-param> |
配置完成之后,即可通过WebApplicationContextUtils.getWebApplicationContext方法在Web应用中获取ApplicationContext引用。