Java事务(五) - 使用动态代理

一. 前言:

上一篇博文中, 我们使用模板模式进行事务管理, 代码看起来已经很简洁了, 但是还是不太完美,

我们依然需要在service层编写和事务相关的代码, 即我们需要在service层宗声明一个TransactionTemplate.

本篇文章中, 我们将使用Java提供的动态代理来完成事务处理, 你将看到无论在service层还是在dao层都不会

有事务处理代码

二. 例子:

1. 代码结构图:

2. TransactionProxy

/**
 * 动态代理
 */
public class TransactionProxy {

	public static Object proxyFor(Object object) {
		return Proxy.newProxyInstance(
										object.getClass().getClassLoader(),
										object.getClass().getInterfaces(),
										new TransactionInvocationHandler(object)
									 );
	}
}

class TransactionInvocationHandler implements InvocationHandler {
	private Object proxy;

	TransactionInvocationHandler(Object object) {
		this.proxy = object;
	}

	public Object invoke(Object obj, Method method, Object[] objects) throws Throwable {
		TransactionManager.beginTransaction();
		Object result = null;
		try {
			// 调用业务方法
			result = method.invoke(proxy, objects);
			TransactionManager.commit();
		} catch (Exception e) {
			TransactionManager.rollback();
		} finally {
			TransactionManager.close();
		}
		return result;
	}
}

拦截service层的transfer方法, 在调用之前加入事务准备工作, 然后调用原来的transfer方法,

之后根据transfer方法是否执行成功决定commit还是rollback

3. 接口类AccountService

/**
 * 业务逻辑层接口
 */
public interface AccountService{
	public void transfer(Account outAccount, Account inAccount, int money) throws SQLException;
}

使用动态代理, 被代理类和代理类必须要实现相同的接口

4. 业务实现类AccountServiceImpl

/**
 * 业务逻辑层
 */
public class AccountServiceImpl implements AccountService {

	@Override
	public void transfer(Account outAccount, Account inAccount, int money) throws SQLException {
		// 查询两个账户
		AccountDAO accountDAO = new AccountDAO();
		outAccount = accountDAO.findAccountById(outAccount.getId());
		inAccount = accountDAO.findAccountById(inAccount.getId());

		// 转账 - 修改原账户金额
		outAccount.setMoney(outAccount.getMoney() - money);
		inAccount.setMoney(inAccount.getMoney() + money);

		// 更新账户金额
		accountDAO.update(outAccount);
		accountDAO.update(inAccount);
	}
}

5. 测试类:

public class TransferTest {

	@Test
	public void transferTest() throws SQLException {
		Account out = new Account();
		out.setId(1);

		Account in = new Account();
		in.setId(2);

		AccountService accountService = new AccountServiceImpl();

		// 获取accountService代理
		AccountService accountServiceProxy = (AccountService) TransactionProxy.proxyFor(accountService);
		accountServiceProxy.transfer(out, in, 100);
	}
}

调用proxyFor方法, 传入需要被代理的对象, 返回一个代理对象, 代理对象条用transfer方法会被加入事务处理

三. 总结:

通过动态代理, AccountServiceImpl中所有public方法都被代理了, 即它们都被加入事务中, 这对于service层中所有方法都需要和数据库打交道的情况是可以的, 然而对于service层中不需要和数据库打交道的public方法, 这样做虽然不会报错, 但是却显得多余.

参考文章: http://www.davenkin.me/post/2013-02-24/40049235086

时间: 2024-11-08 19:15:58

Java事务(五) - 使用动态代理的相关文章

学习Spring必学的Java基础知识(2)----动态代理

学习Spring必学的Java基础知识(2)----动态代理 引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓“登高必自卑,涉远必自迩”.以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系列分别介绍这些Java基础知识,希望对大家有所帮助.): [1] Java反射知识-->Spring IoC :http://www.iteye.com/topic/1123081 [2] Java动态代理-->Spring AOP :http://www

简谈Java 反射机制,动态代理

谈谈 Java 反射机制,动态代理是基于什么原理?小编整理了一些java进阶学习资料和面试题,需要资料的请加JAVA高阶学习Q群:701136382 这是小编创建的java高阶学习交流群,加群一起交流学习深造.群里也有小编整理的2019年最新最全的java高阶学习资料! 反射机制 Java 语言提供的一种基础功能,赋予程序在运行时自省(introspect,官方用语)的能力.可以在运行时通过提供完整的"包名+类名.class"得到某个对象的类型. 功能 在运行时能判断任意一个对象所属的

Java语言中反射动态代理接口的解释与演示

Java语言中反射动态代理接口的解释与演示 Java在JDK1.3的时候引入了动态代理机制.可以运用在框架编程与平台编程时候捕获事件.审核数据.日志等功能实现,首先看一下设计模式的UML图解: 当你调用一个接口API时候,实际实现类继承该接口,调用时候经过proxy实现. 在Java中动态代理实现的两个关键接口类与class类分别如下: java.lang.reflect.Proxy java.lang.reflect.InvocationHandler 我们下面就通过InvocationHan

java反射机制与动态代理

在学习HadoopRPC时,用到了函数调用,函数调用都是采用的java的反射机制和动态代理来实现的,所以现在回顾下java的反射和动态代理的相关知识. 一.反射 JAVA反射机制定义: JAVA反射机制是java程序在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 反射就是把Java类中的各种成分映射成相应的Java类. Java反射机制主要提供了以下功能: 1

Java中两种动态代理的实现

本文介绍了java中两种动态代理的实现方法,Spring的动态代理也是基于这两种方法的.直接附上源码: 1.JDK实现 使用JDK实现动态代理必须使用接口 接口Work.java public interface Work { public void work(); } 实现类WorkImpl.java public class WorkImpl implements Work { @Override public void work() { System.out.println("我在工作&q

Java进阶之 JDK动态代理与Cglib动态代理

一.动态代理概述: 与静态代理对照(关于静态代理的介绍 可以阅读上一篇:JAVA设计模式之 代理模式[Proxy Pattern]), 动态代理类的字节码是在程序运行时由Java反射机制动态生成. 注意: 1.AspectJ是采用编译时生成AOP代理类,具有更好的性能,但是需要使用特定的编译器进行处理 2.Spring AOP采用运行时生成AOP代理类,无需使用特定编译器进行处理,但是性能相对于AspectJ较差 二.JDK动态代理 [对有实现接口的对象做代理] 1.JDK动态代理中 需要了解的

Java重要技术(27)动态代理之查看代理对象的类型信息

1.1. 查看动态代理类的各种信息 通过反射机制可以获取Proxy创建的动态代理类的各种信息,包括实现的接口,构造函数,方法等.查看到这些信息后,可以更好的理解为什么动态代理这么使用. /** * @Title: ProxyTest.java * @Package com.test.javatechnology.proxy * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年3月26日 下午5:36:28

JAVA学习--反射之动态代理模式

1 import java.lang.reflect.InvocationHandler; 2 import java.lang.reflect.Method; 3 import java.lang.reflect.Proxy; 4 5 //动态代理的使用,体会反射是动态语言的关键 6 interface Subject { 7 void action(); 8 } 9 10 // 被代理类 11 class RealSubject implements Subject { 12 public

Java核心技术点之动态代理

本篇博文会从代理的概念出发,介绍Java中动态代理技术的使用,并进一步探索它的实现原理.由于个人水平有限,叙述中难免出现不清晰或是不准确的地方,希望大家可以指正,谢谢大家:) 一.概述 1. 什么是代理 我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家“委托”代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道背后的厂家究竟是谁,也就是说,“委托者”对我们来说是不可见的:其次,微商代理主要以朋友圈的人为目标客户,这就相当于为厂家做了一次对客户群体的“过滤”.我们把微商代理