Spring中频繁使用了工厂模式,相对于一般的工厂模式做了优化,所以这里简单的模拟下,作为学习档案。
外部引用的jar包下载:http://www.jdom.org
Jdom参考文章:http://www.ibm.com/developerworks/cn/xml/x-jdom/
工厂模式一般有三种:
工厂模式在《Java与模式》中分为三类:
1)简单工厂模式(Simple Factory)
2)工厂方法模式(Factory Method)
3)抽象工厂模式(Abstract Factory)
介绍三类的好文章很多,google就好了。
区别:(这里工厂产生的类称为产品)
简单工厂模式:用来生产同一等级结构中的任意产品。对与增加新的产品,无能为力。
工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
说白了,工厂方法虽然可以很好扩展产品种类,但是每次增加产品就要添加一个工厂,会导致工厂泛滥的情况,而抽象工厂模式每次可以生产一系列的产品,但是产品扩展方面局限性又大,spring中的工厂模式采用配置文件的方式很好的解决了他们的短板。
文件清单:BeanFactory.java:工厂接口类
BuildPathXMLApplicationContext.java:文件解析的实现
Movable.java:交通工具接口
Car.java:交工工具实现
Plane.java:交工工具实现
Test.java:测试类
applicationContext.xml:配置文件
文件清单一:BeanFactory.java
package com.lzz.myspringIOC;
/**
* 定义工厂接口
* @author Administrator
*
*/
public interface BeanFactory {
public Object getBean(String beanName);
}
文件清单二:BuildPathXMLApplicationContext.java
package com.lzz.myspringIOC;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.jdom2.xpath.XPath;
/**
* 读取配置文件的bean,并生成实例对象,放在一个map中等待调用
* @author Administrator
*
*/
public class BuildPathXMLApplicationContext implements BeanFactory {
private Map<String, Object> container=new HashMap<String, Object>();
public BuildPathXMLApplicationContext(String fileName) throws Exception{
//通过xml的解析得到bean的id和class名称,并创建实例,存储到msp中
SAXBuilder sb = new SAXBuilder();
Document doc = sb.build(
BuildPathXMLApplicationContext.class.getClassLoader().getResourceAsStream(fileName));
Element root = doc.getRootElement();
System.out.println(root);
List list = XPath.selectNodes(root, "/beans/bean");
System.out.println(list.size());
for(int i=0;i<list.size();i++){
Element beans = (Element) list.get(i);
String id = beans.getAttributeValue("id");
String clazzName=beans.getAttributeValue("class");
System.out.println(id+" "+clazzName);
container.put(id, Class.forName(clazzName).newInstance());
}
}
public Object getBean(String beanName){
return container.get(beanName);
}
}
文件清单三:
Movable.java
package com.lzz.myspringIOC;
/**
* 所有交通工具要实现的类
* @author lzz
*
*/
public interface Movable {
public void run();
}
文件清单四:Car.java
package com.lzz.myspringIOC;
public class Car implements Movable{
public void run(){
System.out.println("小汽车。。。嘀嘀嘀");
}
}
文件清单五:
Plane.java
package com.lzz.myspringIOC;
public class Plane implements Movable {
public void run() {
System.out.println("plane.......");
}
}
文件清单六: Test.java
package com.lzz.myspringIOC;
/**
* 添加新的"产品"的时候,只要修改配置文件就可以使用了
* 解决了工厂方法的不能生产系列"产品"的问题
* 又解决了抽象工厂方法中不能添加"新产品"的问题
* @author lzz
*
*/
public class Test {
public static void main(String[] args) throws Exception {
BeanFactory bf=new BuildPathXMLApplicationContext("com/lzz/myspringIOC/applicationContext.xml");
//配置文件的CLASSPATH下的路径
Object o=bf.getBean("v"); //配置文件中bean的id属性,是car还是plane只要修改配置文件就好了
Movable m=(Movable)o; //这里使用接口实现多态,当配置文件更改的时候,就不需要更改了
m.run();
}
}
文件清单七:
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="v" class="com.lzz.myspringIOC.Plane">
</bean>
</beans>
测试结果:
[Element: <beans/>]
1
v com.lzz.myspringIOC.Plane
plane.......
本文出自 “orangleliu笔记本” 博客,请务必保留此出处http://blog.csdn.net/orangleliu/article/details/38309351