容器工厂(原型)
容器工厂
对于容器工厂的了解可以是:创建一个核心容器,用于存放已经注册的实例。
学习过spring 的童鞋都知道,Spring 框架里面便有一个巨大的容器。
而本次学习的容器工厂便是参照Spring的理念。
通过解析XML读取里面的属性,并利用反射来创建改实现类的实例。
以下是我们需要准备的类
我们先试用手机的案例进行学习。
package factory; /** * 手机 */ public abstract class Phone { /** * 抽象的打电话的行为 */ public abstract void call(); }
/** * OppO */ public class OppoPhone extends Phone { @Override public void call() { System.out.println("使用Oppo手机打电话"); } }
package factory; /** * 小米 */ public class MiPhone extends Phone { @Override public void call() { System.out.println("使用小米手机打电话"); } }
创建好工厂后,我们在来配置XML文件,
beans.xml文件创建在src目录下
<?xml version="1.0" encoding="UTF-8"?> <beans> <!-- bean可以是任意的对象,id是为这个对象在容器中的唯一标识 class属性指定对象的完整类名 scope表示对象的创建形式,单例还是原型,默认是单例--> <bean id="OppoPhone" class="factory.OppoPhone" scope="singleton"/> <bean id="MiPhone" class="factory.MiPhone"/> </beans>
创建好beans.xml后重点来了,
我们要创建一个容器
通过解析XML读取里面的属性,并利用反射来创建改实现类的实例
解析XML配置文件,我们需要用到dom4j。
下面是开始创建容器
package containerfactory; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 容器工厂 * Created by Administrator on 2017/11/27. */ public class ContainerFactory{ //创建一个核心容器,用于存放所有已经注册的实例 private static Map<String,Object> container = new HashMap<String,Object>(); //初始化配置文件,使用dom4j来解析 public ContainerFactory(String resourcePath){ init(resourcePath); } /** * 初始化容器 * @param resourcePath 传入xml文件名 */ private void init(String resourcePath){ //创建SAX解析器 SAXReader reader = new SAXReader(); try { //读取xml文件,并构建一个document对象 Document doc = reader.read(Thread.currentThread().getContextClassLoader().getResourceAsStream(resourcePath)); //获取document的根元素 Element root = doc.getRootElement(); //获取所有的元素 List<Element> list = root.elements(); //循环遍历,解析子元素的属性 for(Element e:list){ //获取id属性的值 String id = e.attributeValue("id"); //获取clas属性的值 String className=e.attributeValue("class"); //将信息放入容器中 container.put(id,Class.forName(className).newInstance()); } } catch (Exception e) { throw new RuntimeException(e); } } /** * 提供一个从容器中获取实例的方法 */ public Object getBean(String id){ return container.get(id); } /** * 重载一个泛型的方法 */ public <T> T getBean(String id,Class<T> clazz){ return (T) container.get(id); } } }
主方法入口
测试一
public class Main { public static void main(String[] args) { ContainerFactory factory = new ContainerFactory("beans.xml"); Phone phone1 = (Phone) factory.getBean("MiPhone"); Phone phone2 = (Phone) factory.getBean("MiPhone"); phone1.call(); System.out.println(phone1==phone2); } }
结果为:
使用Oppo手机打电话
true
测试二
public class Main { public static void main(String[] args) { ContainerFactory factory = new ContainerFactory("beans.xml"); Phone phone1 = factory.getBean("OppoPhone", Phone.class); Phone phone2 = factory.getBean("MiPhone",Phone.class); System.out.println(phone1==phone2); } }
结果为:false