EJB:JAVA中的商业应用组件技术(Enterprise Java Bean)
控制反转/反向控制 inversion of control
依赖注入:dependency injection
所有的类的创建、销毁都由spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。
IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。
理解了IoC和DI的概念后,一切都将变得简单明了,剩下的工作只是在spring的框架中堆积木而已。
在Spring中,两个最基本最重要的包是 org.springframework.beans
org.springframework.context.
这两个包中的代码为Spring的反向控制特性(也叫作依赖注射)提供了基础。
BeanFactory提供了一种先进的配置机制来管理任何种类bean(对象),这种配置机制考虑到任何一种可能的存储方式。
ApplicationContext建立在BeanFactory之上,并增加了其他功能,比如更容易同Spring AOP特性整合,消息资源处理(用于国际化),事件传递,以声明的方式创建ApplicationContext,可选的父上下文和与应用层相关的上下文(比如WebApplicationContext),以及其他方面的增强。
BeanFactory提供了配置框架和基本的功能,而ApplicationContext为它增加了更强的功能,这些功能中的一些或许更加接近J2EE并且围绕企业级应用。一般来说,ApplicationContext是BeanFactory的完全超集,任何BeanFactory功能和行为的描述也同样被认为适用于ApplicationContext。
用户有时不能确定BeanFactory和ApplicationContext中哪一个在特定场合下更适合。通常大部分在J2EE环境的应用中,最好选择使用ApplicationContext,因为它不仅提供了BeanFactory的所有的特性以及它自己附加的特性,而且还提供以声明的方式使用一些功能,这通常是令人满意的。
BeanFactory主要是在非常关注内存使用的情况下(比如在一个每kb都要计算的applet中)使用,而且也不需要用到ApplicationContext的所有特性。
BeanFactory实际上是实例化,配置和管理众多bean的容器。这些bean通常会彼此合作,因而它们之间会产生依赖。
BeanFactory使用的配置数据可以反映这些依赖关系(一些依赖关系可能不像配置数据一样可见,而是在运行期作为bean之间程序交互的函数)。
一个BeanFactory可以用接口org.springframework.beans.factory.BeanFactory表示,这个接口有多个实现。最常使用的简单的BeanFactory实现是org.springframework.beans.factory.xml.XmlBeanFactory。(这里提醒一下:ApplicationContext是BeanFactory的子类,所以大多数的用户更喜欢用ApplicationContext的XML形式)。
虽然大多数情况下,几乎所有被BeanFactory管理的用户代码都不需要知道BeanFactory,但是BeanFactory还是以某种方式实例化。
可以使用下面的代码实例化BeanFactory:
InputStream is = new FileInputStream(“beans.xml”);
XmlBeanFactory factory = new XmlBeanFactory(is);
或者
ClassPathResource res = new ClassPathResource(“beans.xml”);
XmlBeanFactory factory = new XmlBeanFactory(res);
或者
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[]{“applicationContext.xml”,“applicationContext-part2.xml”});
//of course,an ApplicationContext is just a BeanFactory
BeanFactory factory = (BeanFactory) appContext;
很多情况下,用户代码不需要实例化BeanFactory,因为Spring框架代码会做这件事。例如,web层提供支持代码,在J2EE web应用启动过程中自动载入一个Spring ApplicationContext。这个声明过程在这里描述:
编程操作BeanFactory将会在后面提到,下面部分将集中描述BeanFactory的配置。
一个最基本的BeanFactory配置由一个或多个它所管理的Bean定义组成。在一个XmlBeanFactory中,根节点beans中包含一个或多个bean元素。
<?xml version=“1.0” encoding=“UTF-8”>
<!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://www.springframework.org/dtd/spring-beans.dtd”>
<beans>
<bean id=“...” class=“...”>
...
</bean>
<bean id=“...” class=“...”>
...
</bean>
...
</beans>
BeanDefinition
一个XmlBeanFactory中的Bean定义包括的内容有:
·classname:这通常是bean的真正的实现类。但是如果一个bean使用一个静态工厂方法所创建而不是被普通的构造函数创建,那么这实际上就是工厂类的classname。
·bean行为配置元素:它声明这个bean在容器的行为方式(比如prototype或singleton,自动装配模式,依赖检查模式,初始化和析构方法)
·构造函数的参数和新创建bean需要的属性:举一个例子,一个管理连接池的bean使用的连接数目(即可以指定为一个属性,也可以作为一个构造函数参数),或者池的大小限制。
·和这个bean工作相关的其他bean:比如它的合作者(同样可以作为属性或者构造函数的参数)。这个也被叫作依赖。
将上面列出的概念直接转化为组成bean的一组元素:
class;id和name;singleton或prototype;构造函数参数;bean的属性;自动装配模式;依赖检查模式;初始化模式;析构方法
注意bean定义可以表示为真正的接口org.springframework.beans.factory.config.BeanDefinition以及它的各种子接口和实现。然而,绝大多数的用户代码不需要与BeanDefination直接接触。