package com.qdsx.drp.util;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
/**
* 采用动态代理封装事务
* @author Administrator
*
*/
publicclass TransactionHandler implements InvocationHandler {
private Object targetObject;
public Object newProxyInstance(Object targetObject){//目标targetObject都是。。manager
this.targetObject = targetObject;
//目标的ClassLoader装载器,目标的接口,TransactionHandler -- 创建出Proxy
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Connection conn = null;
Object ret = null;
try {
conn = ConnectionManager.getConnection();
if( method.getName().startsWith("add")||
method.getName().startsWith("del")||
method.getName().startsWith("modify")){
//以以上3种开头方法名对应的方法中,手动开启事务
ConnectionManager.beginTransaction(conn);
}
//调用目标的业务逻辑方法
ret = method.invoke(targetObject, args);
if(!conn.getAutoCommit()){//如果非自动提交,是手动事务(以上执行过)
//手动提交
ConnectionManager.commitTransaction(conn);
}
} catch (Exception e) {
e.printStackTrace();
//动态代理把自定义异常包装成了InvocationtargetException,Application是一个target属性(使用debug可见)
if(e instanceof InvocationTargetException){
InvocationTargetException ex = (InvocationTargetException)e;
throw ex.getTargetException();//这是我的自定义异常ApplicationException
}
//回滚事务
ConnectionManager.rollbackTransaction(conn);
thrownew ApplicationException("操作失败!");
}finally{
//关闭Connection 并从ThreadLocal中清除
ConnectionManager.closeConnection();
}
return ret;
}
}
目标类所在:
publicclass FlowCardManagerImpl implements FlowCardManager {
private FlowCardDao flowCardDao = null;
public FlowCardManagerImpl(){
flowCardDao = (FlowCardDao) BeanFactory.getInstance().getDaoObject(FlowCardDao.class);
}
@Override
publicvoid addFlowCard(FlowCard flowCard) throws ApplicationException {
Connection conn = null;
try {
//生成流向单单号
String flowCardVouNo = flowCardDao.generateVouNo();
//添加流向单主信息
flowCardDao.addFlowCardMaster(flowCardVouNo, flowCard);
//添加流向单明细信息
flowCardDao.addFlowCardDetail(flowCardVouNo, flowCard.getFlowCardDetailList());
} catch (DaoException e) {
e.printStackTrace();
thrownew ApplicationException("添加流向单失败!");
}
}
}
使用:
package com.qdsx.drp.util;
import java.util.HashMap;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.qdsx.drp.flowcard.manager.FlowCardManager;
/**
* 抽象工厂,主要创建两个系列的产品
* 1.Manager系列产品
* 2.Dao系列产品
* @author Administrator
*
*/
publicclass BeanFactory {
/**
* key = 配置文件中id值
* value = 对应了改Id的对象
*/
private Map serviceMap = new HashMap();
private Map daoMap = new HashMap();
privatefinal String beansConfigFile = "beans-config.xml";
private Document doc;
privatestatic BeanFactory instance = new BeanFactory();
private BeanFactory(){
try {
doc = new SAXReader().read(Thread.currentThread().getContextClassLoader().getResourceAsStream(beansConfigFile));
} catch (DocumentException e) {
e.printStackTrace();
thrownew RuntimeException("LoadConfigFile fail");
}
}
publicstatic BeanFactory getInstance(){
returninstance;
}
/**
* 根据产品编号取得Service系列产品
* @param serviceId
* @return
*/
publicsynchronized Object getServiceObject(Class c){//要求创建单实例,在创建时用同步(单例中的改造动作同步)
//如果已经存在相关对象实例,直接返回
if(serviceMap.containsKey(c.getName())){
returnserviceMap.get(c.getName());
}
System.out.println("//service[@id='"+c.getName()+"']");
Element beanElt = (Element)doc.selectSingleNode("//service[@id='"+c.getName()+"']");
String className = beanElt.attributeValue("class");
Object service = null;
try {
service = Class.forName(className).newInstance();
//采用动态代理包装service
TransactionHandler transactionHandler = new TransactionHandler();
service = transactionHandler.newProxyInstance(service);
//将建好的对象放入Map中,以便以后直接使用
serviceMap.put(c.getName(), service);
} catch (Exception e) {
e.printStackTrace();
thrownew RuntimeException();
}
return service;
}
/**
* 根据产品编号取得Dao系列产品
* @param daoId
* @return
*/
publicsynchronized Object getDaoObject(Class c){//类的Class对象作参数
//如果已经存在相关对象实例,直接返回
if(daoMap.containsKey(c.getName())){
returndaoMap.get(c.getName());
}
Element beanElt = (Element)doc.selectSingleNode("//dao[@id=\""+c.getName()+"\"]");
String className = beanElt.attributeValue("class");
Object dao = null;
try {
dao = Class.forName(className).newInstance();
//将建好的对象放入Map中,以便以后直接使用
daoMap.put(c.getName(), dao);
} catch (Exception e) {
e.printStackTrace();
thrownew RuntimeException();
}
return dao;
}
publicstaticvoid main(String[] args) {
FlowCardManager flowCardManager = (FlowCardManager) BeanFactory.getInstance().getServiceObject(FlowCardManager.class);
System.out.println(flowCardManager);
}
}