一、目的
有时候项目中用的是SqlServer数据库,有时候又会换成Oracle,或者有时候要用MySQL,如何做才能充分复用代码?根据以上需求,业务逻辑层不会变动,我们只需要变动业务逻辑层所依赖的Dao层就可以。
二、什么是反射机制
简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。
三、实现
先看一下这个demo的宏观结构:
1、采用抽象工厂建立物料Item的dao层(抽象工厂、抽象产品、具体工厂、具体产品);在配置文件sys_config中写出具体的工厂。
<config> <dao-factory> <item-dao-factory>drp.basedata.dao.ItemDaoFactory4Oracle</item-dao-factory> </dao-factory> </config>
2、采用dom4j读取sys_config配置文件中的内容。把这些操作都封装在XMLConfitReader这个类中。注意:必须引用2个关键jar包,否则会报错。(dom4j和jaxen这2个jar包)
package xx.util; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class XMLConfitReader { //单例懒汉模式 private static XMLConfitReader instance= null; private Map<String, String> daoFactoryMap = new HashMap<String, String>(); //构造函数 private XMLConfitReader() { //创建文件读取流 SAXReader reader = new SAXReader(); //指定要加载读取的xml文件 InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("sys-config.xml"); try { //生成文档对应实体 Document doc = reader.read(in); //读取文档内容 List daoFactoryList = doc.selectNodes("/config/dao-factory/*"); for (int i = 0; i < daoFactoryList.size(); i++) { Element daoFactoryElt = (Element)daoFactoryList.get(i); String tabNameString = daoFactoryElt.getName(); String tabTextString = daoFactoryElt.getText(); daoFactoryMap.put(tabNameString, tabTextString); } } catch (DocumentException e) { e.printStackTrace(); } } public static synchronized XMLConfitReader getInstance() { if (instance == null) { instance = new XMLConfitReader(); } return instance; } /* * 根据标签名取得DaoFactory的名字 */ public String getDaoFactory(String name) { return daoFactoryMap.get(name); } }
3、客户端调用(ItemManagerImpl业务逻辑层调用它对应的Dao产品)
public class ItemManagerImpl implements ItemManager { private ItemDaoFactory factory =null; @Override public void addItem(Item item) { //拿到配置文件中的根节点名称 String className = XMLConfitReader.getInstance().getDaoFactory("item-dao-factory"); try { //反射机制生成对象实例装载到内存 factory = (ItemDaoFactory)Class.forName(className).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } //根据反射出的对象factory去创建dao ItemDao itemDao = factory.createItemDao(); Connection conn = null; itemDao.addItem(conn, item); } }