一、目的
有时候项目中用的是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);
}
}