动态代理实现横切——封装事务
来源:互联网 发布:mac怎么打开xlsx 编辑:程序博客网 时间:2024/05/14 19:36
上节课中,通过现象2可知道:如果对各个实现相同的控制,则需要重复写大量的代码。比如说,写日志,事务的开启,关闭,回滚等一系列操作。
但是在开发的过程中,如果经常注意以上的开发,那开发效率将很低的。而且还容易出错。
面对上面的问题,如果只是面向对象的编程。那开发的时候,程序员不仅要专注于业务逻辑的Coding,而且还要在后面写上日志的处理办法,事务的开启关闭等一系列与业务逻辑无关的代码。log.write(class,operate)……
效率上肯定是要打折扣的。而且,把这种重复性的工作交给人力。是非常的容易出现问题的。
现在,要想提高效率。重复的工作交给机器。程序员专心Coding业务逻辑。
面向切面的编程,可以解决这种问题。
前提:事务的控制,发生在B层,dal层是对数据的访问。而业务逻辑的整合在B层。所以需要对B层中的方法,都加上事务。
取得B层实现,是通过工厂取得。
用动态代理封装事务:
package com.bjpowernode.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;/** * 采用动态代理封装事务 */public class TransactionHandler implements InvocationHandler {private Object targetObject;public Object newProxyInstance(Object targetObject){this.targetObject=targetObject;return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);}public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Connection conn=null;Object ret=null;try {//从ThreadLocal中取得Connectionconn=ConnectionManager.getConnection();if(method.getName().startsWith("add") ||method.getName().startsWith("del")||method.getName().startsWith("modify")){//手动开启事务ConnectionManager.beginTransaction(conn);}//调用目标对象的业务逻辑方法ret=method.invoke(targetObject, args);if (!conn.getAutoCommit()) {ConnectionManager.commitTransaction(conn);}} catch (Exception e) {e.printStackTrace();if (e instanceof InvocationTargetException) {InvocationTargetException ete=(InvocationTargetException)e;throw ete.getTargetException();}//回滚事务ConnectionManager.rollbackTransaction(conn);throw new ApplicationException("操作失败!");}finally{ConnectionManager.closeConnection();}return ret;}}
通过上面的方法,可以对B层的对象 进行一个包装的过程,使得对 add 、del、modify开头的方法。包装上一层事务的 开启 提交 回滚等一系列操作。
获取B层实现的方法:
/** * 根据产品编号取得Service系列产品 * @param beanId * @return */public synchronized Object getServiceObject(Class c){if(serviceMap.containsKey(c.getName())){return serviceMap.get(c.getName());}Element beanElt=(Element) doc.selectSingleNode("//service[@id=\""+c.getName()+"\"]");String className=beanElt.attributeValue("class");//System.out.println(className);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();throw new RuntimeException("创建Service失败!");}return service;}
在获取B层对象实例的时候, 进行包装事务。
通过上面getServiceObject获取得到的B层对象,在调用增删改操作的时候,都会有事务控制。这样程序员在开发的过程中就可以专心的开发业务逻辑。而不用思考什时候需要开启事务,什么情况需要提交,什么时候需要回滚等一系列与业务逻辑无关的操作。
在此之前,一直以为实现面向切面的编程需要使用Spring.AOP 通过学习的深入,才发现,面向切面的编程是一种思想,不管用什么技术实现。
面向对象的编程加上面向切面的编程。才会让编程更加有乐趣,更加有效率。
- 动态代理实现横切——封装事务
- 代理模式深入学习(二)——实现动态代理对事务的封装
- 动态代理封装事务
- 采用动态代理对事务进行封装
- 动态代理模式封装事务详解
- 采用动态代理对事务进行封装
- Proxy(动态代理)封装(service层的)事务
- 黑马程序员——day14事务和动态代理
- TransactionHandler类,描述封装事务和connection的动态代理类的类,目标类是manager实现类,提供事务的功能
- 使用ThreadLocal与JDK动态代理 实现事务AOP管理
- 【Java基础】动态代理实现AOP之控制事务
- 使用DBUtils、动态代理以及注解实现事务控制
- Java JDK动态代理实现自己的事务管理器
- 【Java技术点滴】——代理模式及其对事务封装
- 代理模式之动态代理的实现——CGLib
- AOP实现原理——动态代理
- JDK动态代理和CGLIB动态代理,实现Spring注解管理事务区别。
- 代理模式—动态代理
- ActionBar 兼容低版本 时 v7jar包的导入使用指南和资源
- python爬虫学习-爬取百度贴吧图片并保存
- Android如何实现模糊的半透明窗口
- Tomcat注册成系统服务并修改内存
- 数字三角形
- 动态代理实现横切——封装事务
- 【剑指Offer面试题】 九度OJ1387:斐波那契数列
- 产生冠军
- SCOI2009生日蛋糕
- HTTP请求和HTTP响应介绍
- 一刀斩:SVN客户端访问URL失败--请求的名称有效,但是找不到请求的类型
- UI中 View、Label的方法
- KnockoutJS的使用及分析
- [3D游戏开发]Early ZBuffer