BeanFactory 是 Spring 的“心脏”。它就是 Spring IoC 容器的真面目。Spring 使用 BeanFactory 来实例化、配置和管理 Bean。可是,在大多数状况咱们并不直接使用 BeanFactory,而是使用 ApplicationContext。它也是 BeanFactory 的一个实现,可是它添加了一系列“框架”的特征,好比:国际化支持、资源访问、事件传播等。ApplicationContext 咱们将在后面章节中介绍。java
BeanFactory 实际上是一个接口-org.springframework.beans.factory.BeanFactory,它能够配置和管理几乎全部的 Java 类。固然,具体的工做是由实现 BeanFactory 接口的实现类完成。咱们最经常使用的 BeanFactory 实现是 org.springframework.beans.factory.xml.XmlBeanFactory。它从 XML 文件中读取 Bean 的定义信息。当 BeanFactory 被建立时,Spring 验证每一个 Bean 的配置。固然,要等 Bean 建立以后才能设置 Bean 的属性。单例(Singleton)Bean 在启动时就会被 BeanFactory 实例化,其它的 Bean 在请求时建立。根据 BeanFactory 的 Java 文档(Javadocs)介绍,“Bean 定义的持久化方式没有任何的限制:LDAP、RDBMS、XML、属性文件,等等”。如今 Spring 已提供了 XML 文件和属性文件的实现。无疑,XML 文件是定义 Bean 的最佳方式。spring
BeanFactory 是初始化 Bean 和调用它们生命周期方法的“吃苦耐劳者”。注意,BeanFactory 只能管理单例(Singleton)Bean 的生命周期。它不能管理原型(prototype,非单例)Bean 的生命周期。这是由于原型 Bean 实例被建立以后便被传给了客户端,容器失去了对它们的引用。app
首先咱们创建一个BeanFactory接口框架
1 package com.spring; 2 3 public interface BeanFactory { 4 Object getBean(String id); 5 }
而后创建一个BeanFactory的实现类ClassPathXmlApplicationContext.javadom
1 package com.spring; 2 3 import java.util.HashMap; 4 import java.util.List; 5 import java.util.Map; 6 7 import org.dom4j.Document; 8 import org.dom4j.DocumentException; 9 import org.dom4j.Element; 10 import org.dom4j.io.SAXReader; 11 12 13 public class ClassPathXmlApplicationContext implements BeanFactory { 14 private Map<String, Object> beans = new HashMap<String, Object>(); 15 public ClassPathXmlApplicationContext(String fileName) throws Exception{ 16 SAXReader reader = new SAXReader(); 17 Document document = reader.read(this.getClass().getClassLoader().getResourceAsStream(fileName)); 18 List<Element> elements = document.selectNodes("/beans/bean"); 19 for (Element e : elements) { 20 String id = e.attributeValue("id"); 21 String value = e.attributeValue("class"); 22 Object o = Class.forName(value).newInstance(); 23 beans.put(id, o); 24 } 25 } 26 27 public Object getBean(String id) { 28 return beans.get(id); 29 } 30 31 }
而后配置applicationContext.xml函数
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans> 3 <bean id="c" class="com.spring.Car"></bean> 4 <bean id="p" class="com.spring.Plane"></bean> 5 </beans>
建立类的时候顺便演示一下工厂模式,其实BeanFactory它也是一种工厂模式的。post
1 package com.spring; 2 3 public interface Moveable { 4 void run(); 5 }
1 package com.spring; 2 3 public class Car implements Moveable{ 4 5 public void run(){ 6 System.out.println("拖着四个轮子满街跑car·····"); 7 } 8 }
1 package com.spring; 2 3 public class Plane implements Moveable{ 4 5 public void run() { 6 System.out.println("拖着翅膀天空飞plane......"); 7 } 8 9 }
如今来看一看效果吧,写一个类测试一下:测试
1 package com.spring; 2 3 import org.dom4j.DocumentException; 4 5 public class Test { 6 7 /** 8 * @param args 9 * @throws DocumentException 10 */ 11 public static void main(String[] args) throws Exception { 12 BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml"); 13 Object o = factory.getBean("c"); 14 Moveable m = (Moveable)o; 15 m.run(); 16 } 17 18 }
因为Map容器里面保存的是Object类型,因此经过getBean()方法取出来的对象要强制类型转换。this
下图描述了 Bean 的生命周期。它是由 IoC 容器控制。IoC 容器定义 Bean 操做的规则,即 Bean 的定义(BeanDefinition)。Bean 的定义包含了 BeanFactory 在建立 Bean 实例时须要的全部信息。BeanFactory 首先经过构造函数建立一个 Bean 实例,以后它会执行 Bean 实例的一系列以前初始化动做,初始化结束 Bean 将进入准备就绪(ready)状态,这时应用程序就能够获取这些 Bean 实例了。最后,当你销毁单例(Singleton)Bean 时,它会调用相应的销毁方法,结束 Bean 实例的生命周期。spa
前面的用户注册的例子中,咱们已经使用 Spring 定义了一个用户持久化类:
<bean id="userDao" class="com.dev.spring.simple.MemoryUserDao"/>
这是一个最简单的 Bean 定义。它相似于调用了语句:
MemoryUserDao userDao = new MemoryUserDao()。
id属性必须是一个有效的 XML ID,这意味着它在整个 XML 文档中必须惟一。它是一个 Bean 的“终身代号(9527)”。同时你也能够用 name 属性为 Bean 定义一个或多个别名(用逗号或空格分开多个别名)。name 属性容许出现任意非法的 XML 字母。例如:
<bean id="userDao" name="userDao*_1, userDao*_2" class="com.dev.spring.simple.MemoryUserDao"/>。
class属性定义了这个 Bean 的全限定类名(包名+类名)。Spring 能管理几乎全部的 Java 类。通常状况,这个 Java 类会有一个默认的构造函数,用set
方法设置依赖的属性。
Bean 元素出了上面的两个属性以外,还有不少其它属性。说明以下:
<bean id="beanId"(1) name="beanName"(2) class="beanClass"(3) parent="parentBean"(4) abstract="true | false"(5) singleton="true | false"(6) lazy-init="true | false | default"(7) autowire="no | byName | byType | constructor | autodetect | default"(8) dependency-check = "none | objects | simple | all | default"(9) depends-on="dependsOnBean"(10) init-method="method"(11) destroy-method="method"(12) factory-method="method"(13) factory-bean="bean">(14) </bean>
(1).id: Bean 的惟一标识名。它必须是合法的 XML ID,在整个 XML 文档中惟一。 (2).name: 用来为 id 建立一个或多个别名。它能够是任意的字母符合。多个别名之间用逗号或空格分开。 (3).class: 用来定义类的全限定名(包名+类名)。只有子类 Bean 不用定义该属性。 (4).parent: 子类 Bean 定义它所引用它的父类 Bean。这时前面的 class 属性失效。子类 Bean 会继承父类 Bean 的全部属性,子类 Bean 也能够覆盖父类 Bean 的属性。注意:子类 Bean 和父类 Bean 是同一个 Java 类。 (5).abstract(默认为”false”):用来定义 Bean 是否为抽象 Bean。它表示这个 Bean 将不会被实例化,通常用于父类 Bean,由于父类 Bean 主要是供子类 Bean 继承使用。 (6).singleton(默认为“true”):定义 Bean 是不是 Singleton(单例)。若是设为“true”,则在 BeanFactory 做用范围内,只维护此 Bean 的一个实例。若是设为“flase”,Bean将是 Prototype(原型)状态,BeanFactory 将为每次 Bean 请求建立一个新的 Bean 实例。 (7).lazy-init(默认为“default”):用来定义这个 Bean 是否实现懒初始化。若是为“true”,它将在 BeanFactory 启动时初始化全部的 Singleton Bean。反之,若是为“false”,它只在 Bean 请求时才开始建立 Singleton Bean。 (8).autowire(自动装配,默认为“default”):它定义了 Bean 的自动装载方式。 “no”:不使用自动装配功能。 “byName”:经过 Bean 的属性名实现自动装配。 “byType”:经过 Bean 的类型实现自动装配。 “constructor”:相似于 byType,但它是用于构造函数的参数的自动组装。 “autodetect”:经过 Bean 类的检讨机制(introspection)决定是使用“constructor”仍是使用“byType”。 (9).dependency-check(依赖检查,默认为“default”):它用来确保 Bean 组件经过 JavaBean 描述的因此依赖关系都获得知足。在与自动装配功能一块儿使用时,它特别有用。 none:不进行依赖检查。 objects:只作对象间依赖的检查。 simple:只作原始类型和 String 类型依赖的检查 all:对全部类型的依赖进行检查。它包括了前面的 objects 和 simple。 (10).depends-on(依赖对象):这个 Bean 在初始化时依赖的对象,这个对象会在这个 Bean 初始化以前建立。 (11).init-method:用来定义 Bean 的初始化方法,它会在 Bean 组装以后调用。它必须是一个无参数的方法。 (12).destroy-method:用来定义 Bean 的销毁方法,它在 BeanFactory 关闭时调用。一样,它也必须是一个无参数的方法。它只能应用于singleton Bean。 (13).factory-method:定义建立该 Bean 对象的工厂方法。它用于下面的“factory-bean”,表示这个 Bean 是经过工厂方法建立。此时,“class”属性失效。 (14).factory-bean:定义建立该 Bean 对象的工厂类。若是使用了“factory-bean”则“class”属性失效。(1).id: Bean 的惟一标识名。它必须是合法的 XML ID,在整个 XML 文档中惟一。 (2).name: 用来为 id 建立一个或多个别名。它能够是任意的字母符合。多个别名之间用逗号或空格分开。 (3).class: 用来定义类的全限定名(包名+类名)。只有子类 Bean 不用定义该属性。 (4).parent: 子类 Bean 定义它所引用它的父类 Bean。这时前面的 class 属性失效。子类 Bean 会继承父类 Bean 的全部属性,子类 Bean 也能够覆盖父类 Bean 的属性。注意:子类 Bean 和父类 Bean 是同一个 Java 类。 (5).abstract(默认为”false”):用来定义 Bean 是否为抽象 Bean。它表示这个 Bean 将不会被实例化,通常用于父类 Bean,由于父类 Bean 主要是供子类 Bean 继承使用。 (6).singleton(默认为“true”):定义 Bean 是不是 Singleton(单例)。若是设为“true”,则在 BeanFactory 做用范围内,只维护此 Bean 的一个实例。若是设为“flase”,Bean将是 Prototype(原型)状态,BeanFactory 将为每次 Bean 请求建立一个新的 Bean 实例。 (7).lazy-init(默认为“default”):用来定义这个 Bean 是否实现懒初始化。若是为“true”,它将在 BeanFactory 启动时初始化全部的 Singleton Bean。反之,若是为“false”,它只在 Bean 请求时才开始建立 Singleton Bean。 (8).autowire(自动装配,默认为“default”):它定义了 Bean 的自动装载方式。 “no”:不使用自动装配功能。 “byName”:经过 Bean 的属性名实现自动装配。 “byType”:经过 Bean 的类型实现自动装配。 “constructor”:相似于 byType,但它是用于构造函数的参数的自动组装。 “autodetect”:经过 Bean 类的检讨机制(introspection)决定是使用“constructor”仍是使用“byType”。 (9).dependency-check(依赖检查,默认为“default”):它用来确保 Bean 组件经过 JavaBean 描述的因此依赖关系都获得知足。在与自动装配功能一块儿使用时,它特别有用。 none:不进行依赖检查。 objects:只作对象间依赖的检查。 simple:只作原始类型和 String 类型依赖的检查 all:对全部类型的依赖进行检查。它包括了前面的 objects 和 simple。 (10).depends-on(依赖对象):这个 Bean 在初始化时依赖的对象,这个对象会在这个 Bean 初始化以前建立。 (11).init-method:用来定义 Bean 的初始化方法,它会在 Bean 组装以后调用。它必须是一个无参数的方法。 (12).destroy-method:用来定义 Bean 的销毁方法,它在 BeanFactory 关闭时调用。一样,它也必须是一个无参数的方法。它只能应用于singleton Bean。 (13).factory-method:定义建立该 Bean 对象的工厂方法。它用于下面的“factory-bean”,表示这个 Bean 是经过工厂方法建立。此时,“class”属性失效。 (14).factory-bean:定义建立该 Bean 对象的工厂类。若是使用了“factory-bean”则“class”属性失效。