当从BeanFactory中通过getBean()方法获取一个bean的时候,BeanFactory会经过如下的步骤来构建Bean的实例,这正是实例化Bean的过程:
从名字上看就是 Spring 的一个 Bean 工厂。如果单从工厂模式的角度思考,它就是用来“生产 Bean ”,然后提供给客户端。
1、调用Bean的默认构造方法,或者在指定的构造方法,生成bean实例(暂称为instance1);
3、如果Bean的配置文件中注入了Bean属性值,则在instance1基础上进行属性注入形成instance2,这种注入是覆盖性的。
2、如果Bean实现了InitializingBean接口,则调用afterPropertiesSet()方法,来改变或操作instance2,得到instance3;
4、如果Bean的配置文件中指定了init-method="init"属性,则会调用指定的初始化方法,则在instance3的基础上调用初始化方法init(),将对象最终初始化为instance4;当然,这个初始化的名字是任意的。
instance1、2、3、4是一个实例在不同阶段的状态。
上述是spring中的beanfactory功能 下面我们利用dom4j来解析applicationContext.xml,借助于java的反射技术,来创建bean实例
我们依然是针对接口编程 我们的演示接口为移动 采用两个类来实现这个接口 一个命名为汽车 另外一个命名为飞机
public interface Moveable { void run(); }
汽车实现
public class Car implements Moveable{ public void run(){ System.out.println("拖着四个轮子满街跑car·····"); } }
飞机实现
public class Plane implements Moveable{ public void run() { System.out.println("拖着翅膀天空飞plane......"); } }
按照以前的方式 我们要测试上述 建立一个main函数
public class Test { public static void main(String[] args) throws Exception { Car car = new Car(); car.run(); } }
对的,这样简简单单的就能够测试了 现在我们吃饱了没事干了 我们引入第三方创建bean实例,在在主函数中通过getBean方法获得这个bean,并且
强转为我们需要的类型 如下
Object o = factory.getBean("c"); Moveable m = (Moveable)o; m.run();
如何实现上面的呢 首先我们需要一个类工厂能够根据我们实现的类例如Car,Plane来动态的创建Bean 这就用到了
Object o = Class.forName(className).newInstance(); 也就是之前的第三种反射方法
上面的className怎么来的呢 恩 通过dom4j 来解析配置文件
首先我们需要一个工厂类的接口
public interface BeanFactory { Object getBean(String id); }
提供getBean方法
接着我们去实现这个工厂类
public ClassPathXmlApplicationContext(String fileName) throws Exception{ SAXReader reader = new SAXReader(); Document document = reader.read(this.getClass().getClassLoader().getResourceAsStream(fileName)); Element root = document.getRootElement(); List list = root.elements(); for(int index= 0 ; index < list.size();index++){ Element bean = (Element) list.get(index); String id = bean.attributeValue("id"); String className = bean.attributeValue("class"); Object o = Class.forName(className).newInstance(); beans.put(id,o); } }
实现getBean方法方法
public Object getBean(String id) { return beans.get(id); }
上述的dom4j读取的配置文件为
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <bean id="c" class="com.spring.Car"></bean> <bean id="p" class="com.spring.Plane"></bean> </beans>
好了 大功告成了 “我们吃饱撑了” 通过第三方bean工厂类 来实现了上述功能
public class Test { /** * @param args * @throws DocumentException */ public static void main(String[] args) throws Exception { BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml"); Object o = factory.getBean("c"); Moveable m = (Moveable)o; m.run(); } }
下面是运行结果
拖着四个轮子满街跑car·····