实现原理:通过读取解析xml配置文件,拿到相应的类名和类的包全名,将类名存到map集合中的key值,再通过反射得到相应的实例,从而动态的生产不同的对象出来
1.新建两个接口,Phone的接口,里面有两个方法,打电话和发消息的方法;Pad的接口,玩游戏的方法
2.三个实现类,HuaiPhone类和VivoPhone类实现Phone接口的所有方法,PadPhone类实现Pad接口的方法
3.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="HuaiPhone" class="edu.nf.factory.easy.Impl.HuaiPhone"/> <bean id="PadPhone" class="edu.nf.factory.easy.Impl.PadPhone"/> <bean id="VivoPhone" class="edu.nf.factory.easy.Impl.VivoPhone"/> </beans>
4、最重要的一步:新建一个工厂类,这个工厂可以动态的生产不同的对象
package edu.nf.factory.vesselFactory; import edu.nf.factory.easy.Phone; import edu.nf.factory.utils.Reflect; import org.dom4j.*; import org.dom4j.io.SAXReader; import javax.annotation.Resources; import java.io.File; import java.io.InputStream; import java.net.URL; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * 描述: * 容器工厂 * * @author lance * @create 2018-09-28 11:29 */ public class VesselFac { private static Map<String,Object> map = new HashMap<String, Object>(); static { //新建一个xml读取器 SAXReader reader = new SAXReader(); ClassLoader classLoader = VesselFac.class.getClassLoader(); //得到一个xml的文件流 InputStream is = classLoader.getResourceAsStream("beans.xml"); try { //以文件流方式解析成doc文档 Document doc = reader.read(is); //得到一个根节点 Element ele = doc.getRootElement(); //得到所有的字节点 Iterator<Element> it = ele.elementIterator(); //循环所有的子节点 while (it.hasNext()){ Element elem = it.next(); String name = elem.attributeValue("id"); String className = elem.attributeValue("class"); map.put(name,className); } //根据包名反射得到实例 for(String m : map.keySet()){ Object instance = Class.forName((String)map.get(m)).newInstance(); map.put(m,instance); } } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } /** * 获取实例的方法(根据key值来获取相应的实例) * @param key * @param clazz * @param <T> * @return */ public static <T> T getObject(String key, Class<T> clazz){ return (T)map.get(key); } }
5、测试: