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

采用动态代理对事务进行封装

 
阅读更多

如果采用三层架构的方式开发,在业务逻辑层不可避免的要手动操作事务,所以在业务逻辑层会出现很多与业务逻辑无关的:

Connection conn = ConnectionManage.GetConnection();
ConnectionManage.beginTransaction(conn);ConnectionManage.commitTransaction(conn);等等代码。

不仅不合理,而且是重复劳动,程序开发的一个原则就是杜绝重复劳动,做到良好的封装。

这里,我们就采用动态代理对事务进行封装,使我们的业务逻辑层不再出现有关事务的代码。

package com.jialin.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 jialin
 *
 */
public class TransactionHandler implements InvocationHandler {

	private Object targetObject;

	/**
	 * 获取目标类的代理
	 * @param targetObject
	 * @return
	 */
	public Object newProxyInstance(Object targetObject) {
		this.targetObject = targetObject;
		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 {
			// 从ThreadLocal中取得Connection。ConnectionManage是对connection的封装
			conn = ConnectionManage.GetConnection();
			
			//如果是以add,del,modify开头的方法,则手动开启事务
			if (method.getName().startsWith("add")
					|| method.getName().startsWith("del")
					|| method.getName().startsWith("modify")) {
				// 手动控制事务提交
				ConnectionManage.beginTransaction(conn);
			}
			// 调用目标对象的业务逻辑方法
			ret = method.invoke(targetObject, args);
			
			//如果事务为手动提交方式,则手动提交事务
			if (!conn.getAutoCommit()) {
				// 提交事务
				ConnectionManage.commitTransaction(conn);
			}
		} catch (Exception e) {
			//如果事务为手动提交方式,则手动回滚事务
			if (!conn.getAutoCommit()) {
				// 回滚事务
				ConnectionManage.rollbackTransaction(conn);
			}
			e.printStackTrace();
			
			if (e instanceof InvocationTargetException) {
				InvocationTargetException ete = (InvocationTargetException) e;
				throw ete.getTargetException();
			}
			
			throw new Exception("操作失败!");
		} finally {
			//关闭连接
			ConnectionManage.closeConnection();
		}
		return ret;

	}

}


原理:当我们在工厂中获取业务逻辑层对象的时候,我们获取的并不是目标对象,而是目标对象的代理,代理替我们管理事务的开启,提交,回滚,与关闭

在工厂中用动态代理包装业务逻辑对象

public synchronized Object GetServiceBean(Class c) {
		if (ServiceMap.containsKey(c.getName())) {
			return ServiceMap.get(c.getName());
		}

		Element beanEle = (Element) doc.selectSingleNode("//Service[@id=\""
				+ c.getName() + "\"]");
		String className = beanEle.attributeValue("class");
		// System.out.print(className);
		Object serviceBean = null;
		try {
			serviceBean = Class.forName(className).newInstance();
			
			//采用动态代理包装Service
			TransactionHandler transactionHandler = new TransactionHandler();
			//得到代理
			serviceBean = transactionHandler.newProxyInstance(serviceBean);
			
			ServiceMap.put(c.getName(), serviceBean);
		} catch (Exception e) {
			throw new RuntimeException();
		}
		return serviceBean;

	}


//获取的并不是目标对象,而是目标对象的代理

userManager = (UserManager) getBeanFactory().GetServiceBean(UserManager.class);


分享到:
评论

相关推荐

    利用动态代理提炼Servlet

    为了提高代码的可复用性和灵活性,开发者通常会采用设计模式或者技术手段对Servlet进行封装。本篇文章将深入探讨如何利用Java的动态代理机制来提炼Servlet,实现更高效、更模块化的代码结构。 动态代理,是Java提供...

    spring 事务代理配置

    它基于AOP(面向切面编程)原则,在运行时动态创建代理对象,这些代理对象封装了事务管理行为。当调用代理方法时,代理会拦截调用并自动开启、提交或回滚事务,从而实现事务的管理。 #### 配置步骤 1. **定义数据...

    AOP技术及其在J2EE中动态代理实现

    在AOP框架(例如Spring AOP)的支持下,这些代理类会在运行时拦截对业务对象的方法调用,并插入相应的通知逻辑。 在J2EE开发中,AOP技术的应用主要体现在以下几个方面: 1. 事务管理:通过AOP,开发者可以轻松实现...

    封装.NET增删查改

    动态代理则可以在运行时创建对象的代理,拦截并处理方法调用,如在执行SQL前添加事务管理或日志记录。 在设计数据访问层时,可以采用工厂模式或仓储模式。工厂模式用于创建数据访问对象,根据传入的参数动态生成...

    ADO.NET Entity Framework使用封装示范代码

    封装使得单元测试变得更加容易,因为你可以针对具体的数据访问层进行模拟测试,而不必依赖真实的数据库。这有助于确保代码的质量和稳定性。 8. **最佳实践** 在实际应用中,遵循一些最佳实践是非常重要的,如:...

    代理模式的理解

    为了进一步提高系统的可扩展性和灵活性,我们可以采用动态代理机制,通过反射动态生成代理类,而不是硬编码代理类。这种方式允许我们在运行时根据需要创建不同的代理实例,而无需修改源代码。 ```java import java....

    JAVA设计模式之事务处理.pdf

    - 使用代理模式(Proxy Pattern):创建一个事务代理类,将事务控制逻辑封装在代理中,而不是直接在业务对象中。这样可以减少业务对象的复杂性,并提供统一的事务管理接口。 - 使用装饰者模式(Decorator Pattern)...

    Socket_tcp多事务处理程序框架

    4. 代理模式:可以创建一个代理类,封装Socket的读写操作,便于添加日志、错误处理等功能。 五、异常处理 在Socket编程中,必须妥善处理网络异常,如连接中断、数据传输错误等。Java的异常处理机制(try-catch-...

    从一个输出日志的实例分析Java的代理机制.doc

    动态代理则是在运行时动态生成代理对象,这通常通过Java的`java.lang.reflect.Proxy`类和`InvocationHandler`接口来实现。在动态代理中,我们定义一个`InvocationHandler`实现类,重写`invoke`方法,在这个方法内...

    用Hibernate和Spring开发事务持久层.rar_spring

    结合Spring和Hibernate进行事务管理,通常会采用Spring的JDBC抽象层或者Hibernate的SessionFactory来处理数据库交互。Spring通过AOP代理在合适的时候调用Hibernate的Session方法,控制事务的开启、提交、回滚等行为...

    Spring-AOP .pptx

    - Spring AOP通过动态代理技术在运行时织入增强代码,采用JDK动态代理或CGLib动态代理两种机制。 - 动态代理是AOP的核心,它规范化了如何在不修改原有代码的情况下插入横切逻辑。 5. **动态代理** - JDK动态代理...

    OSIP协议栈及其在SIP用户代理中的应用

    - **SDP解析**:不仅包括对SDP会话类型进行解析,还包括对会话类型的初始化和释放操作,以及对整个SDP包的基本操作。 - **URI解析**:负责解析SIP URI中的host、port、username、password等信息,并进行相应的设置...

    C#面向对象设计模式纵横谈(13):Proxy 代理模式(结构型模式)

    这样做的好处在于可以对访问行为进行封装,同时不影响原有对象的功能。代理模式可以通过以下几种方式实现: - **远程代理**:当目标对象位于远程服务器上时,本地代理可以作为中间人,负责处理与远程对象的通信。 -...

    SpringFramework常见知识点.md

    1. **XML 配置**:早期 Spring 主要采用这种方式进行配置,但现在已较少推荐使用。 2. **注解配置**:推荐使用,可以在类级别或方法级别添加注解来实现依赖注入。 3. **Java API 配置**:通常与注解配置结合使用,...

    soap:webservice 客户端(根据jdk soap 进行的封装), 服务端(cxf)

    在描述中提到,客户端是基于JDK SOAP进行封装的,这意味着开发者可能创建了一个更易用的抽象层,简化了上述API的使用,提供了更灵活的地址配置,比如动态设置服务URL,或者通过配置文件管理多个服务地址。...

    【框架源码篇 03】Spring源码手写篇-手写AOP

    Spring AOP主要采用动态代理的方式实现运行时织入。 手写Spring AOP,我们需要实现以下几个关键步骤: 1. **代理机制**:Spring使用JDK动态代理和CGLIB动态代理实现切面的织入。对于实现了接口的目标对象,Spring...

    qfedu三段Spring以及Spring整合MyBatis

    - **CGLIB动态代理**:适用于没有实现接口的情况,即可以直接对类进行代理。 #### 二、AOP编程 1. **AOP概念介绍**: - **定义**:AOP(Aspect Oriented Programming),即面向切面编程,它是Spring框架的另一个...

    idc网管系统

    本项目结 构上分为表现层、业务层和数据访问层,层次间的依赖关系自下到上。采用的技术有Struts,Spring,Hibernate,Log4J,JDom 等。其中表现层采用Struts框架开发;...为提高性能,采用Servlet Filter实现了缓存代理

Global site tag (gtag.js) - Google Analytics