背景
工厂模式是大家非常熟悉的设计模式,spring BeanFactory将此模式发扬光大,今天就来讲讲,spring IOC容器是如何帮我管理Bean,构造对象的,简单的写了一个demo。
思路如下:
- 解析xml文件,将bean标签的,id,class存储在一个map中
- 获取实例对象时通过id匹配,匹配成功返回该对象
先看下常见的工厂模式
关于什么是工厂模式之前写过一个:https://my.oschina.net/u/923324/blog/744792
创建一个接口类Pizza
package com.spring.xml;
public interface Pizza{
public float getPrice();
}
MargheritaPizza 类
package com.spring.xml;
public class MargheritaPizza implements Pizza{
public float getPrice() {
System.out.println("8.5f");
return 8.5f;
}
}
CalzonePizza 类
public class CalzonePizza implements Pizza{
public float getPrice() {
System.out.println("2.5f");
return 2.5f;
}
}
建立工厂类PizzaFactory
通过传入参数id,选择不同的实例类,如果后续不断的增加新类,会频繁的修改create方法,不符合开闭原则
public class PizzaFactory {
public Pizza create(String id) {
if (id == null) {
throw new IllegalArgumentException("id is null!");
}
if ("Calzone".equals(id)) {
return new CalzonePizza();
}
if ("Margherita".equals(id)) {
return new MargheritaPizza();
}
throw new IllegalArgumentException("Unknown id = " + id);
}
}
采用spring xml 配置的方式实现工厂类的管理
建立一个BeanFactory接口
package com.spring.xml;
2
3 public interface BeanFactory {
4 Object getBean(String id);
5 }
实现类ClassPathXmlApplicationContext.java
BeanFactory实现类,主要功能是解析xml文件,封装bean到map中
public class ClassPathXmlApplicationContext implements BeanFactory {
private Map<String, Object> beans = new HashMap<String, Object>();
public ClassPathXmlApplicationContext(String fileName) throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(this.getClass().getClassLoader().getResourceAsStream(fileName));
List<Element> elements = document.selectNodes("/beans/bean");
for (Element e : elements) {
//获取beanId
String id = e.attributeValue("id");
//获取beanId对于的ClassPath下class全路径名称
String value = e.attributeValue("class");
//通过反射实例化该beanId 的class对象
Object o = Class.forName(value).newInstance();
//封装到一个Map里
beans.put(id, o);
}
}
public Object getBean(String id) {
return beans.get(id);
}
}
applicationContext.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="calzone" class="com.spring.xml.CalzonePizza"></bean>
<bean id="margherita" class="com.spring.xml.MargheritaPizza"></bean>
</beans>
写一个类测试一下
package com.spring.xml;
import org.dom4j.DocumentException;
public class Test {
public static void main(String[] args) throws Exception {
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
Pizza p = (Pizza)factory.getBean("Calzone");
p.getPrice();
}
}
看完代码应该非常清楚,比起原先通过if else来选择不同的实现类方便。