`
jishublog
  • 浏览: 872539 次
文章分类
社区版块
存档分类
最新评论

动态代理封装时事务

 
阅读更多

结合上篇博客《动态代理模式》,我们来使用它来封装一下事务管理,记得以前使用事务,对管理的抽象也仅限于抽离出一个类,通过传入数据库连接,对事务进行开启、提交、回滚等操作,每一个。但是仔细想想我们的业务流程是固定的,哪里使用或不使用事务也是固定的,所以,事务和业务之间并非必须的耦合关系,以下就是通过动态代理将业务和事务解耦。

代理类

TransactionHandler,这个是对事务操作的核心,将需要事务的函数在此处理:

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
 *
 */
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中取得Connection
			conn = 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(ApplicationException e) {
			//回滚事务
			ConnectionManager.rollbackTransaction(conn);
			throw e;
		}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;
	}
}

使用封装的事务

在工厂中创建Service实例时,使用封装的事务。

	/**
	 * 根据产品编号取得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");
		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) {
			throw new RuntimeException();
		}
		return service;
	}

在这里我们需要注意的是,当代理类截获异常后,会对异常进行封装,封装为InvocationTargetException,所以如果要对原异常进行处理,需要对异常进行类型判断再行处理。


更多DRP系列博客,其访问《DRP项目总结》。

分享到:
评论

相关推荐

    Spring AOP与动态代理

    AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并...

    springboot分布式事务解决方案LCN

    对比LCN和saga(华为apache孵化器项目),LCN使用代理连接池封装补偿方法,saga需要手工写补偿方法,相对来说LCN使用更加方便。LCN事务控制原理是由事务模块TxClient下的代理连接池与TxManager的协调配合完成的事务...

    Java_JDBC由浅入深

    14.3.2 动态代理 84 14.4 DBCP数据库连接池的使用 87 第十五节 jdbc轻量级封装 88 15.1 将结果集封装为Map 88 15.1.1 ResultSetMetaData演示 88 15.1.2解决多行记录的问题 89 15.1.3 Map结果集的封装 90 15.2 将结果...

    qt-snmp-subagent:一个简单的Net-SNMP AgentX子代理接口,用于实现MIB模块的Qt(C ++)应用程序

    本质上,QSNMP封装了Net-SNMP库的子代理API,用于使用AgentX协议与SNMP主代理snmpd交换SNMP获取,设置和通知消息。 Net-SNMP主代理(其配置和文档不在QSNMP范围之内)将与Network Management Station(NMS)处理...

    springboot2-spring5-studying:Springboot2,Spring源码学习项目,涉及SpringBoot2自动装配实现机制,Spring AOP动态代理以及IOC各种扩展接口的实现方式

    概述Spring Aop在Spring框架中的布局举足轻重,主要用于实现事务,缓存,安全等功能。主要介绍以下三个方面: Spring AOP多种代理机制相关核心类介绍。 Spring Boot中AOP注解方式源码分析。 Spring Boot 1.x版本和2...

    基于SpringBoot完成扩展、自动化配置,通过封装一系列Starter来让调用者快速集成组件,提高开发效率.zip

    springboot Spring框架是Java平台上的一种开源应用框架,提供具有控制反转...Spring框架具有面向切面编程(AOP)框架,SpringAOP框架基于代理模式,同时运行时可配置;AOP框架主要针对模块之间的交叉关注点进行模块化。

    alloy-worker:面向事务的高可用Web Worker通信框架

    特色面向事务及命名空间的通信封装,支持大规模业务的场景。 Promise化调用代替跨线程事件监听,无缝支持async / await。完整的Worker可用监控指标;全周期工人错误监控。原始码全TypeScript,跨线程数据类型一致性...

    idc网管系统

    本项目结 构上分为表现层、业务层和数据访问层,层次间的依赖关系自下到上。采用的技术有Struts,Spring,Hibernate,Log4J,...事务部分利用Spring的声明式事务管 理。为提高性能,采用Servlet Filter实现了缓存代理

    hibernate精华教程

    使用hibernate编程步骤 1)配置环境,加载hibernate的jar文件,以及...它对底层的事务接口做了封装,底层事务接口包括:JDBC API、JTA(JavaTransactionAPI)、CORBA(CommonObjectRequestBroker Architecture)API。

    javasnmp源码-java_review:复习资料

    JDK动态代理和cgLib动态代理 ​ ​ ​ sprin创建bean过程 ​ ​ SpringMVC常用注解 ​ springMVC处理请求流程/工作流程 ​ ​ SpringMVC @RequestParam,@PathParam,@PathVariable等注解区别 ​ ...

    TCP-IP详解.卷三:TCP事务协议,HTTP,NNTP和UNIX域协议

    24.7 T/TCP:为事务用的TCP扩展 265 24.8 TCP的性能 267 24.9 小结 268 第25章 SNMP:简单网络管理协议 270 25.1 引言 270 25.2 协议 270 25.3 管理信息结构 272 25.4 对象标识符 274 25.5 管理信息库介绍 274 25.6 ...

    java开源包4

    JFile 是 JActor 的文件持久化组件,以及一个高吞吐量的可靠事务日志组件。 Google地图JSP标签库 利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还...

    java代理服务器源码-DDMQ:DDMQ是低延迟、高吞吐、高可用的分布式消息传递产品

    提供实时消息、延时消息和事务消息来满足不同的场景。 通过简单易用的Web Console和简单的SDK Client,开发者可以体验到最简单稳定的消息生产和消费。 特征 消息传递模型:同时支持 P2P 和 Pub/Sub 消息传递模型 ...

    JINI核心技术

    6.3.2 DiscoveryEvent封装了发现信息 115 6.3.3 使用LookupDiscovery控制组播 发现 116 6.3.4 使用LookupLocator来控制单播 发现 123 6.4 发现协议的内部知识 127 6.4.1 组播请求协议 127 6.4.2 组播通告协议 129 ...

    JINI 核心技术

    6.3.2 DiscoveryEvent封装了发现信息 115 6.3.3 使用LookupDiscovery控制组播 发现 116 6.3.4 使用LookupLocator来控制单播 发现 123 6.4 发现协议的内部知识 127 6.4.1 组播请求协议 127 6.4.2 组播通告协议 129 ...

    网站设计方案(完整版).doc

    名词解释: Hibernate: Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对 象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的...

    SSH 框架所需JAR包

    6.cglib-nodep-2.1_3.jar(支持cglib动态代理的包) 如果用BasicDataSource来配置数据库连接,还要加入2个包: 7.commons-pool.jar 8.commons-dbcp.jar Hibernate需要的jar包: 1.hibernate3.jar(hibernate的核心jar...

    SSH 项目 整合jar包

    6.cglib-nodep-2.1_3.jar(支持cglib动态代理的包) 如果用BasicDataSource来配置数据库连接,还要加入2个包: 7.commons-pool.jar 8.commons-dbcp.jar 三、Hibernate需要的jar包: 1.hibernate3.jar(hibernate的...

    图书商城代码

    对request,response进行了代理和包装。 模拟structs2对servlet的封装,通过java的反射机制调用servlet和hibernat对事务的管理。实现了用户登录和注册功能,数据加密,购物车模块,生成订单等功能。

Global site tag (gtag.js) - Google Analytics