【Java技术位】——代理模式及其事务包
背景
项目中我们会遇到这种情况:在几个方法中增加同样的代码,这些代码是与业务无关的,而且以后有可能因为考虑不周或需求变动再或者是其它原因,我们须要对他们进行逐一进行修改。举个详细的样例,比方程序中的日志控制、事务控制等,这些功能是与业务无关的,但却须要将它们与我们的逻辑混在一起。达到一些特殊的需求。
这种情况往往代码都是同样的,能够抽离出来,为了复用,我们能够将这些同样的代码单独封装成的方法,以供其它须要的地方调用,这样对于以后的改动就做到了仅仅改动一处的效果,达到了程序的复用。但另外一个问题便是,将来某一天我们可能不须要这种功能了,我们就须要将调用这些功能的代码逐一进行删除,并且当方法的參数或返回值变动或许要进行每一处调用的改动。
基于以上的问题,我们能够採用代理模式进行解决。
基本介绍
代理模式(Proxy):为其它对象提供一种代理以控制对这个对象的訪问。
直白些说。我们与须要调用的目标对象之间加上一层(代理类),我们便不直接调用曾经的目标对象,而是通过代理类间接调用,这样,我们就能够在代理里做那些抽离出的功能了。
代理模式类图示意
曾经的直接调用方式
使用代理模式抽取公共调用部分
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGZzZnh5dGdiOV9seWc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" height="222" width="441" alt="">
分类
静态:
静态代理中的代理类是看得见摸得着的。编译时就已经确定了要运行的方法。
静态代理存在着代理类过多的问题。为了更加灵活度的实现,我们能够使用动态代理。
动态:代理类执行时确定
使用:
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的拦截机制,使我们能够在调用目标方法前做一些事,在调用目标方法后做一些事。这样就能够达到曾经我们一般的编程理论所不能达到的效果,再加上一些灵活配置的附加应用,代理模式的应用能够说是相当广泛。也为未来的计划,旨在提供了很多其他的思路和想法。
版权声明:本文博客原创文章。博客,未经同意,不得转载。
【Java技术位】——代理模式及其事务包的更多相关文章
- (转)轻松学,Java 中的代理模式及动态代理
背景:讲到反射机制,肯定会想到动态代理. 轻松学,Java 中的代理模式及动态代理 代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强.值得注意的是,代理类和被代理类应该 ...
- Java设计模式之代理模式(静态代理和JDK、CGLib动态代理)以及应用场景
我做了个例子 ,需要可以下载源码:代理模式 1.前言: Spring 的AOP 面向切面编程,是通过动态代理实现的, 由两部分组成:(a) 如果有接口的话 通过 JDK 接口级别的代理 (b) 如果没 ...
- Java设计模式:代理模式(转)
代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.这里使用到编程中的一 ...
- 谈谈Java中的代理模式
首先来看一下代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用, 其特征是代理类与 ...
- java设计模式6——代理模式
java设计模式6--代理模式 1.代理模式介绍: 1.1.为什么要学习代理模式?因为这就是Spring Aop的底层!(SpringAop 和 SpringMvc) 1.2.代理模式的分类: 静态代 ...
- 说说Java中的代理模式
今天看到传智播客李勇老师的JDBC系列的第36节——通过代理模式来保持用户关闭连接的习惯.讲的我彻底蒙蔽了,由于第一次接触代理模式,感到理解很难,在博客园找到一篇文章,先记录如下: 引用自java设计 ...
- Java三种代理模式
本文转自:https://mp.weixin.qq.com/s/nBmbNP2mR7ei-lDsuOxjWg 代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象 ...
- Java设计模式:代理模式(二)
承接上文 三.计数代理 计数代理的应用场景是:当客户程序需要在调用服务提供者对象的方法之前或之后执行日志或者计数等额外功能时,就可以用到技术代理模式.计数代理模式并不是把额外操作的代码直接添加到原服务 ...
- java jdk动态代理模式举例浅析
代理模式概述 代理模式是为了提供额外或不同的操作,而插入的用来替代”实际”对象的对象,这些操作涉及到与”实际”对象的通信,因此代理通常充当中间人角色. java中常用的动态代理模式为jdk动态代理和c ...
随机推荐
- _00021 尼娜抹微笑伊拉克_谁的的最离奇的异常第二阶段 Jedis pool.returnResource(jedis)
笔者博文:妳那伊抹微笑 博客地址:http://blog.csdn.net/u012185296 博文标题:_00021 妳那伊抹微笑_谁的异常最诡异第二期之 Jedis pool.returnRes ...
- COCO-Android开发框架公布
一. COCO-Android说明 二. COCO-Android结构图 三. COCOBuild 四. COCOFrame 一.COCO-Android说明 1. COCO-Android是支撑An ...
- BGP协议学习总结
BGP学习总结 BGP是目前使用的唯一的自治系统间的路由协议,它是一种矢量路由协议,基于TCP的179号端口,它采用单播增量更新的方式更新路由,与其他的路由协议不同的是,BGP只要TCP可达,就可以建 ...
- Java參数传递方式
原文:http://blog.sina.com.cn/s/blog_59ca2c2a0100qhjx.html,我作了些改动并添加了一个实例,添加对照 本文通过内存模型的方式来讨论一下Java中的參数 ...
- 【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】
传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因 ...
- Knockout应用开发指南 第八章:简单应用举例(2)
原文:Knockout应用开发指南 第八章:简单应用举例(2) 5 Control types 这个例子,对view model没有什么特殊的展示,只是展示如何绑定到各种元素上(例如,select ...
- c++对象指针-01(转载)
1.指向对像的指针在建立对像时,编译系统会为每一个对像分配一定的存储空间,以存放其成员,对像空间的起始地址就是对像的指针.可以定义一个指针变量,用来存和对像的指针.如果有一个类:class Time{ ...
- Learning Cocos2d-x for WP8(5)——详解Menu菜单
原文:Learning Cocos2d-x for WP8(5)--详解Menu菜单 C#(wp7)兄弟篇Learning Cocos2d-x for XNA(5)——详解Menu菜单 菜单是游戏必不 ...
- 怎样在屏幕上显示多个alv
本文解说怎样在屏幕上显示多个alv. 实现这种需求关键是下面几点(举例:在屏幕上显示4个alv): 1.须要定义4个alv control 2.由于有4个alv control,于是就须要定义4个容器 ...
- C# 制作Java +Mysql+Tomcat 环境安装程序,一键式安装
原文:C# 制作Java +Mysql+Tomcat 环境安装程序,一键式安装 要求: JDK.Mysql.Tomcat三者制作成一个安装包, 不能单独安装,安装过程不显示三者的界面, 安装完成要配置 ...