【Java技术点滴】——代理模式及其对事务封装

背景

项目中我们会遇到这样的情况:在几个方法中加入相同的代码,这些代码是与业务无关的,并且以后有可能由于考虑不周或需求变动再或者是其他原因,我们需要对他们进行逐一进行改动。举个具体的例子,比如程序中的日志控制、事务控制等,这些功能是与业务无关的,但却需要将它们与我们的逻辑混在一起,达到一些特殊的需求。

这样的情况往往代码都是相同的,可以抽离出来,为了复用,我们可以将这些相同的代码单独封装成的方法,以供其他需要的地方调用,这样对于以后的修改就做到了只修改一处的效果,达到了程序的复用,但另外一个问题便是,将来某一天我们可能不需要这样的功能了,我们就需要将调用这些功能的代码逐一进行删除,而且当方法的参数或返回值变动也许要进行每一处调用的修改。

基于以上的问题,我们可以采用代理模式进行解决。

基本介绍

代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。

直白些说,我们与需要调用的目标对象之间加上一层(代理类),我们便不直接调用以前的目标对象,而是通过代理类间接调用,这样,我们就可以在代理里做那些抽离出的功能了。

代理模式类图示意

以前的直接调用方式

使用代理模式抽取公共调用部分

分类

静态:

静态代理中的代理类是看得见摸得着的,编译时就已经确定了要执行的方法。静态代理存在着代理类过多的问题。为了更加灵活度的实现,我们可以使用动态代理。

动态:代理类运行时确定

使用:

1.目标类必须实现某接口

2.建立代理对象的控制类

实现InvocationHandler,封装根据目标对象生成代理类的方法,调用方首先调用Proxy的newProxyInstance方法(此部分可以应用工厂模式进行封装,以后可以进行去除或改变代理类),生成并转换为代理类,调用此类的目标方法,则可回调到InvocationHandler实现类的invoke方法

示例-动态代理封装事务

public class TransactionHandler implements InvocationHandler {

	private Object targetObject;

	public Object newProxyInstance(Object targetObject){
		this.targetObject = targetObject;
		return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
					<span style="font-family:KaiTi_GB2312;">      </span>targetObject.getClass().getInterfaces(), this);
	}

	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("save") ||
			   method.getName().startsWith("remove") ||
			   method.getName().startsWith("modify")){
			   //手动控制事务提交
			       ConnectionManager.beginTransaction(conn);
			}
			//调用目标对象的业务逻辑方法
			ret = method.invoke(targetObject, args);

			//判断,当AutoCommit设置为false的前提下控制提交
			if(!conn.getAutoCommit()){
				//提交事务
				ConnectionManager.commit(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;
	}
}

注:此示例中的类ConnectionManage具体实现参见【Java技术点滴】——ThreadLocal封装JDBC事务操作

经过此类的封装,我们便可以实现在Service层中需要进行事务操作的地方便不用每次都写事务相关的代码了,只要为Service层类生成代理,回调此类的的Invoke方法就可以实现事务的控制,这样就达到了很好的复用和更高的可维护性。

总结

正因为代理模式为我们带来了类似于Filter的拦截机制,使我们可以在调用目标方法前做一些事,在调用目标方法后做一些事,这样就可以达到以前我们一般的编程理论所不能达到的效果,再加上一些灵活配置的附加应用,代理模式的应用可以说是相当广泛,也为今后的程序设计提供了更多了思路与思想。

时间: 2024-10-29 19:10:35

【Java技术点滴】——代理模式及其对事务封装的相关文章

JAVA设计模式之代理模式

学编程吧JAVA设计模式之代理模式发布了,欢迎通过xuebiancheng8.com来访问 一.概述 给某一个对象提供一个代理,并由代理对象来完成对原对象的访问.代理模式是一种对象结构型模式. 二.适用场景 当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口. 三.UML类图 四.参与者 1.接口类:Subject 它声明了真实访问者和代理访问者的共同接口,客户端通常需要针对接口角色进行编程. 2.代理类

java设计模式6——代理模式

java设计模式6--代理模式 1.代理模式介绍: 1.1.为什么要学习代理模式?因为这就是Spring Aop的底层!(SpringAop 和 SpringMvc) 1.2.代理模式的分类: 静态代理 动态代理 1.3.代理模式关系图(以租房子为例) 2.静态代理 2.1.角色分析: 抽象角色:一般会使用接口或者抽象类来解决 真实角色:被代理的角色 代理客户:代理真实角色.代理真实角色后,我们一般会做一些附属的操作 客户:访问代理对象的人 2.2.例1(租房子演示) 2.2.1.抽象角色实现(

JAVA设计模式(3)----代理模式

1.  什么是代理模式?Proxy Pattern 代理模式定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 通俗的讲,代理模式就是我很忙没空理你,你要想找我可以先找我的代理人,代理人和被代理人继承同一个接口.代理人虽然不能干活,但是被代理的人可以干活. 这个例子中有水浒传中的这么几个人:名垂青史的潘金莲,王婆,西门大官人.西门庆想要找潘金莲,需要找王婆做代理.首先定义一个接口:Kin

Java中的代理模式

1.什么是代理模式 代理模式:就是为其他对象提供一种代理以控制对这个对象的访问. 代理可以在不改动目标对象的基础上,增加其他额外的功能(扩展功能). 举个例子来说明代理的作用: 一般我们想邀请明星来当我们的代言人,我们并不能直接联系到明星,而是通过其经纪人,来告诉经纪人我们需要和明星进行合作,然后通过经纪人来转达给明星.,明星只需要做好代言工作就好,其他繁琐的事情就交于经纪人就可以.这里的经经纪人就是一个代理对象,明星就是一个目标对象. 用图表示如下: 2.三种代理模式  2.1 静态代理 静态

JAVA设计模式之 代理模式【Proxy Pattern】

一.概述 给某一个对象提供一个代理,并由代理对象来完成对原对象的访问.代理模式是一种对象结构型模式. 二.适用场景 当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口. 三.UML类图 四.参与者 1.接口类:Subject 它声明了真实访问者和代理访问者的共同接口,客户端通常需要针对接口角色进行编程. 2.代理类:ProxySubject 包含了对真实(委托)对象(RealSubject)的引用,在实现

JAVA设计模式学习--代理模式

学习还是先从定义开始,反复的琢磨对模式的定义会让自己更深刻的记住. 代理模式定义:在某些场景下,系统中的目标对象不能被直接引用或者不适合直接引用,这时需要一个代理,起中介的作用以达到控制和增强目标对象. 代理模式分类:静态代理.动态代理. 代理模式结构: 1.抽象主题 2.真实主题 3.代理对象 上代码 静态代理 //抽象主题 public interface Target { public void display(); } //真实主题 public class RealTarget imp

Java与设计模式-代理模式

代理模式也称为委托模式,属于结构型设计模式,为其他对象提供一种代理,以控制对这个对象的访问.这么听起来很难理解,生活中代理的例子也是很多的,毕业了要找房子,怎样又快又好的找到自己心仪的房子,必须通过租房代理:想要买火车票,火车站太远,我们可以选择代理点进行购票.代码模式的UML类图如下: 应用场景:当无法或不想直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口.下面我们以"秋菊打官司"为例,讲解一下代

java设计优化--代理模式

代理模式使用代理对象完成用户的请求,屏蔽用户对真实对象的访问. 代理模式的用途很多,比如因为安全原因,需要屏蔽客户端直接访问真实对象:或者在远程调用中,需要使用代理对象处理远程方法中的技术细节:或者为了提升系统,对真是对象进行封装,从而达到延迟加载的目的. 在系统启动时,将消耗资源最多的方法使用代理模式分离,就可以加快系统的启动速度,减少用户的等待时间.在用户真正在做查询是,再由代理类加载真实的类,完成用户请求.这就是使用代理模式达到延迟加载的目的. 1.静态代理实现: 主题接口: 1 publ

Java设计模式:代理模式(一)

问题的提出 现在生活中,常常在微信朋友圈里面看到代购的信息,你想在国外买什么,香港买什么,但是又懒得自己过去,于是常常委托别人帮忙买奶粉买那啥的.这类问题的缘由是因为客户和原产地没有直接的接触,所以需要一个代理(代购)的第三者来实现间接引用.代理对象可以在客户端和目标对象间起到中介作用,而且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务.代理模式是一种很好实现客户对象与代理对象分离的策略.其抽象UML图如下图 代理模式包含如下角色 ISubject:抽象主题角色,是一个接