java之代理设计模式

代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
按照代理的创建时期,代理类可以分为两种。
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。

这里写图片描述

静态代理

  1. 定义一个接口
package cn.itcast.proxy.sh;public interface PersonDao {public void savePerson();public void updatePerson();public void deletePerson();
}

2、 目标类

package cn.itcast.proxy.sh;public class PersonDaoImpl implements PersonDao{public void deletePerson() {System.out.println("delete person");}public void savePerson() {System.out.println("save person");}public void updatePerson() {System.out.println("update person");}
}

3、代理类,包含了目标类和一些额外的操作

package cn.itcast.proxy.sh;public class PersonDaoProxy implements PersonDao{private PersonDao personDao;private Transaction transaction;public PersonDaoProxy(PersonDao personDao,Transaction transactions){this.personDao = personDao;this.transaction = transactions;}public void deletePerson() {this.transaction.beginTransaction();this.personDao.deletePerson();this.transaction.commit();}public void savePerson() {this.transaction.beginTransaction();this.personDao.savePerson();this.transaction.commit();}public void updatePerson() {this.transaction.beginTransaction();this.personDao.updatePerson();this.transaction.commit();}
}

4、使用

package cn.itcast.proxy.sh;import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class ProxyTest {@Testpublic void test(){ApplicationContext context = new ClassPathXmlApplicationContext("cn/itcast/proxy/sh/applicationContext-proxy.xml");PersonDao personDao = (PersonDao)context.getBean("personDao2");personDao.deletePerson();}
}

静态代理的缺点

静态代理模式的缺点:
1、如果一个系统中有100Dao,则创建100个代理对象
2、如果一个dao中有很多方法需要事务,则代理对象的方法中重复代码还是很多
3、由第一点和第二点可以得出:proxy的重用性不强

动态代理

1、产生的代理对象和目标对象实现了共同的接口
jdk动态代理
2、代理对象是目标对象的子类
hibernate: Person person = session.load(Person.class,1L); javassisit
spring:cglib动态代理

jdk的动态代理:
1、因为是用jdk的API做到的
2、代理对象是动态产生的
cglib产生的代理类是目标类的子类

注意事项:
1、拦截器中invoke方法体的内容就是代理对象方法体的内容
2、当客户端执行代理对象.方法时,进入到了拦截器的invoke方法体
3、拦截器中invoke方法的method参数是在调用的时候赋值的

jdk动态代理

定义一个接口

package cn.itcast.jdkproxy.sh;public interface PersonDao {public void savePerson();public void updatePerson();public void deletePerson();
}

目标类

package cn.itcast.jdkproxy.sh;public class PersonDaoImpl implements PersonDao{public void deletePerson() {System.out.println("delete person");}public void savePerson() {System.out.println("save person");}public void updatePerson() {System.out.println("update person");}
}

拦截器

package cn.itcast.jdkproxy.sh;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;/*** 拦截器* @author Think*   1、引入目标类*   2、引入事务*   3、通过构造函数给目标类和事务赋值*   4、填充invoke方法**/
public class PersonInterceptor implements InvocationHandler{private Object target;//目标类private Transaction transaction;//引入事务public PersonInterceptor(Object target,Transaction transaction){this.target = target;this.transaction = transaction;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubthis.transaction.beginTransaction();method.invoke(this.target, args);//调用目标类的方法this.transaction.commit();return null;}}

使用

package cn.itcast.jdkproxy.sh;import java.lang.reflect.Proxy;import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class ProxyTest {@Testpublic void test(){Object target = new PersonDaoImpl();Transaction transaction = new Transaction();PersonInterceptor interceptor = new PersonInterceptor(target, transaction);/*** 1、目标类的类加载器* 2、目标类实现的所有的接口* 3、拦截器*/PersonDao personDao = (PersonDao)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor);personDao.deletePerson();}
}

cglib动态代理

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

目标类

package net.battier.dao.impl;  /** * 这个是没有实现接口的实现类 *  * @author student *  */  public class BookFacadeImpl1 {  public void addBook() {  System.out.println("增加图书的普通方法...");  }  }  

拦截类

package net.battier.proxy;  import java.lang.reflect.Method;  import net.sf.cglib.proxy.Enhancer;  
import net.sf.cglib.proxy.MethodInterceptor;  
import net.sf.cglib.proxy.MethodProxy;  /** * 使用cglib动态代理 *  * @author student *  */  public class BookFacadeCglib implements MethodInterceptor {  private Object target;  /** * 创建代理对象 *  * @param target * @return */  public Object getInstance(Object target) {  this.target = target;  Enhancer enhancer = new Enhancer();  enhancer.setSuperclass(this.target.getClass());  // 回调方法  enhancer.setCallback(this);  // 创建代理对象  return enhancer.create();  }  @Override  // 回调方法  public Object intercept(Object obj, Method method, Object[] args,  MethodProxy proxy) throws Throwable {  System.out.println("事物开始");  proxy.invokeSuper(obj, args);  System.out.println("事物结束");  return null;  }  }  

使用

package net.battier.test;  import net.battier.dao.impl.BookFacadeImpl1;  
import net.battier.proxy.BookFacadeCglib;  public class TestCglib {  public static void main(String[] args) {  BookFacadeCglib cglib=new BookFacadeCglib();  BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1());  bookCglib.addBook();  }  
}  

参考链接

java动态代理(JDK和cglib) - C’est la vie - 博客园

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/494196.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

lisp中的*,**,***

在lisp中“*”除了乘法的作用外,还被用来保存REPL(read-eval-print-loop)中的返回值。其中 * -> 保存最后一次返回值。 ** -> *的上一次值。 *** -> **的上一次值。 例子如下: 而且  * (car /) ** …

为了帮粉丝完成毕业设计,我发现了一款私活神器

一、缘起 不日前,有粉丝找到我,让我帮着做个: 教师管理系统 由于种种借口,我当时把问题交给群友去解决了..... 思来想去,越想越内疚,于是就请教了经常做私活的小伙伴。 必须分享给更多的小伙伴~ 二、揭开面…

狗脸识别APP整合

本文主要包括以下内容 android studio中导入so文件 通过URI获得Bitmap android studio中导入so文件 在main文件夹下建立jniLibs目录,并将so文件拷贝进去即可。 注意 声明的native方法与so文件中定义的方法的包名必须相同 通过URI获得Bitmap private Bitmap …

解析丰田对自动驾驶汽车的愿景:打造更加安全的汽车

丰田高管约翰莱昂纳德在丰田研究所的麻省理工学院车库,在他身后是研究所改造的一辆雷克萨斯选自:Bloomberg来源: 网易科技参与:乐邦约翰莱昂纳德(John Leonard)漫步走到麻省理工学院(MIT)校园里一间单调乏味的一层车库&#xff0c…

C站最全Python库总结丨标准库+高级库

梦想还是要有的,万一别人问呢? 作者:不吃西红柿 简介:CSDN博客专家、蓝桥签约作者、大数据&Python领域优质创作者。 CSDN私信我,回复【资料】领取: 1、100套小编购买的简历模板; 2、1000套…

DeepMind-深度学习: AI革命及其前沿进展 (54页ppt报告)

来源:专知摘要:2018年9 月 9 日-14 日,DeepMind主办的Deep Learning Indaba 2018 大会在南非斯泰伦博斯举行。会上,牛津大学教授和其他15位专家做了《深度学习: AI革命及其前沿进展》的报告。Nando de FreitasNando de Freitas是一…

❤️ 6个Python办公黑科技,工作效率提升100倍!HR小姐姐都馋哭了(附代码)❤️

🍅 作者:不吃西红柿 🍅 简介:CSDN博客专家🏆、信息技术智库公号作者✌。简历模板、职场PPT模板、技术难题交流、面试套路尽管【关注】私聊我。 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 如有…

苹果未来秘密在这里!从神秘组织到七大技术布局

来源:智东西随着人工智能的艰难发展,智能手机增长的放缓, 苹果公司能否第三次重塑自我?在很多方面,苹果仍然是一家以Steve Jobs个人形象制造的公司,专注于颠覆性产品。但今天,苹果走在了十字路口…

❤️ 爬虫分析CSDN大佬之间关系,堪比娱乐圈 ❤️

🍅 作者主页:不吃西红柿 🍅 简介:CSDN博客专家🏆、信息技术智库公号作者✌简历模板、PPT模板、技术资料尽管【关注】私聊我。历史文章目录:https://t.1yb.co/zHJo 🍅 欢迎点赞 👍 …

SSH框架整合

ssh框架整合步骤如下 提示:myeclipse环境、工程环境、tomcat环境的jdk保持一致 1、新建一个工程,把工程的编码为utf-8 2、把jsp的编码形式改成utf-8 3、把jar包放入到lib下 4、建立三个src folder src 存放源代码 config 存放配置文件 hibernate…

关于未来的10点核心思考

作者:尤瓦尔赫拉利 牛津大学历史学博士,全球瞩目的新锐历史学家来源:《今日简史》世界正在变得越来越复杂,我们正在陷入知识的错觉和群体的无知。同时,我们的生活被社交媒体所塑造,真相早已不存在&#xff…

❤️爆肝3万字,最硬核丨Mysql 知识体系、命令全集 【建议收藏 】❤️

🍅 作者主页:不吃西红柿 🍅 简介:CSDN博客专家🏆、信息技术智库公号作者✌ 简历模板、PPT模板、学习资料、面试题库、技术互助【关注我,都给你】 🍅 欢迎点赞 👍 收藏 ⭐留言 &am…

今天专攻POWERSHELL获取本机CPU,内存消耗

PS脚本如下: 1 $Server $env:computername2 #servers CPU Mem Hardinfor 3 $cpu gwmi –computername $Server win32_Processor 4 $men gwmi -ComputerName $Server win32_OperatingSystem 5 $Disks gwmi –Computer: $Server win32_logicaldisk -filter …

证明黎曼猜想的5页论文已发布!最简洁的解读在这里

来源:潇轩社著名数学家阿蒂亚(Michael Atiyah)公开了他为黎曼猜想做的“简洁证明”,论文长度总共5页。借助量子力学中的无量纲常数α(fine structure constant),阿提亚声称解决了复数域上的黎曼…

《Python顶级入门教程》一步一步,是魔鬼的步伐

目录 🍅 1、欲练此功,先知此人 ⚾ 2、Python 语言特性 ❤ 3、Python 特点 🍅 4、Python 行情如何? ✍ 5、Python 怎么学? 5.1 学理论——懂原理 5.2 做练习——会应用 5.3 团队学习——不懂就问 &#x1f34…

C#/C++/Fortran 在32位/64位下数学计算性能对比

测试平台 在我的上一篇博客中对比了VS2010中C#和C在运算密集型程序中的性能。上一篇博客的链接: http://www.cnblogs.com/ytyt2002ytyt/archive/2011/11/24/2261104.html 当时是在AMD 速龙9650 CPU(4核心)下的测试结果。 随着VS2012、Intel Parallel Studio XE 2013…

“光纤之父”高锟离世,感谢他的贡献

来源:云头条据明报报道,香港中文大学前校长、“光纤之父”、2009年诺贝尔物理学奖得主,今天(9月23日)下午在医院离世,享年84岁。高錕1933年11月在中国上海出生,祖贯江苏金山市,出身书…

struts2服务端与android交互

本文主要包括以下内容 android与struts2服务器实现登陆 android从struts2服务器获取list数据 android上传数据到struts2服务器 服务器端代码 package com.easyway.json.android;import java.util.HashMap; import java.util.Map;import javax.servlet.http.HttpServletReque…

爆款专栏《Python 黑科技》目录导航丨进度:12/50

《Python 快速入门专栏丨掌握基础》和《Python 黑科技丨练习应用》由 CSDN 博客专家丨全站排名 Top 8 的硬核博主 不吃西红柿 倾力打造,旨在帮助大家快速入门掌握 Python。 更有学习资料,简历和 PPT 模板,微信公众号 【信息技术智库】关注我&…

干货|2018年中国智能硬件行业现状与发展趋势报告

来源:前瞻产业研究院未来智能实验室是人工智能学家与科学院相关机构联合成立的人工智能,互联网和脑科学交叉研究机构。未来智能实验室的主要工作包括:建立AI智能系统智商评测体系,开展世界人工智能智商评测;开展互联网…