当前位置: 首页 > news >正文

Java中的代理模式

Java中的代理模式

    • 1. 静态代理
    • 2. JDK动态代理
    • 3. CGLib动态代理

1. 静态代理

接口

public interface ICeo {void meeting(String name) throws InterruptedException;
}

目标类

public class Ceo implements ICeo{public void meeting(String name) throws InterruptedException {Thread.sleep(2000);System.out.println("和"+name+"谈成了34亿的项目");}
}

代理类

public class CeoProxy implements ICeo{private Ceo ceo;public CeoProxy(Ceo ceo) {this.ceo = ceo;}@Overridepublic void meeting(String name) throws InterruptedException {System.out.println("秘书登记来访: "+name);StopWatch stopWatch = new StopWatch();stopWatch.start();ceo.meeting(name);stopWatch.stop();double totalTimeMillis = stopWatch.getTotalTimeSeconds();System.out.println("耗时: "+totalTimeMillis);}
}

测试

public class CeoTest {public static void main(String[] args) throws InterruptedException {Ceo ceo = new Ceo();CeoProxy ceoProxy = new CeoProxy(ceo);ceoProxy.meeting("XXX");}
}

2. JDK动态代理

接口

public interface IDao {void select();
}

目标类

public class UserDao implements IDao{@Overridepublic void select() {try {Thread.sleep(2000);System.out.println("select ----");} catch (InterruptedException e) {throw new RuntimeException(e);}}
}

动态代理类
在这里插入图片描述

public class JdkProxy implements InvocationHandler {private Object target;public JdkProxy(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {StopWatch stopWatch = new StopWatch();System.out.println("前置方法");stopWatch.start();Object obj = method.invoke(target, args);stopWatch.stop();System.out.println("后置方法");System.out.println("耗时: "+stopWatch.getTotalTimeSeconds());return obj;}
}

测试

public class DaoTest {public static void main(String[] args) {UserDao userDao = new UserDao();IDao dao = (IDao) Proxy.newProxyInstance(UserDao.class.getClassLoader(), UserDao.class.getInterfaces(), new JdkProxy(new UserDao()));dao.select();}
}

总结:

  1. 动态生成代理类
  2. 通过实现接口生成代理类(目标接口必须实现接口)
  3. 代理类是实现接口的方式
  4. 调用目标类使用反射调用
  5. 目标类调用本类方法只会代理一次

3. CGLib动态代理

在这里插入图片描述

目标类

public class ZlmDao {public void select(){try {Thread.sleep(2000);System.out.println("select ---");} catch (InterruptedException e) {throw new RuntimeException(e);}}
}

代理类

public class CglibProxy implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {StopWatch stopWatch = new StopWatch();stopWatch.start();System.out.println("前置增强");Object result = proxy.invokeSuper(obj, args);stopWatch.stop();System.out.println("后置增强");System.out.println("耗时: "+stopWatch.getTotalTimeSeconds());return result;}
}

测试

public class ZlmDaoTest {public static void main(String[] args) {//实例化增强器Enhancer enhancer = new Enhancer();//设置需要代理的目标类enhancer.setSuperclass(ZlmDao.class);//设置拦截对象回调的实现类enhancer.setCallback(new CglibProxy());//生成代理类ZlmDao zlmDao = (ZlmDao) enhancer.create();zlmDao.select();}
}

总结

  1. 通过ASM第三方框架动态代理
  2. 无需接口(final修饰的类和方法除外)
  3. 代理类通过继承目标类的方式实现代理
  4. 调用目标类,使用子类调用父类的方式直接调用
  5. invokeSuper目标类中调用本类方法会再次代理
  6. incoke目标类中调用本来方法只会调用一次
http://www.lryc.cn/news/104497.html

相关文章:

  • LeetCode每日一题——1331.数组序号转换
  • 2、Tomcat介绍(下)
  • JAVA 正则表达式(heima)
  • 布瑞特单圈绝对值旋转编码器串口数据读取
  • Linux第六章之vim与gcc使用
  • 【Golang】Golang进阶系列教程--为什么说 Go 语言字符串是不可变的?
  • ES开启身份认证
  • Docker安装es以及ik分词器
  • 中断、进程调度、进程切换、系统调用,模式切换的那些事情
  • 使用web-view实现网页端和uni-app端是数据传输
  • Ajax快速入门
  • Google OAuth 2 authorization - Error: redirect_uri_mismatch 400
  • Qt 中操作xml文件和JSON字符串
  • React 基础篇(二)
  • springboot + shiro 下载文件时浏览器提示“无法下载-没有权限”或“无法下载-没有文件”问题
  • ChatGLM-6B 部署与 P-Tuning 微调实战-使用Pycharm实战
  • 【雕爷学编程】MicroPython动手做(11)——搭建掌控板IDE开发环境四种
  • uniapp android底部弹框
  • hashedWheelTimer类
  • 【自动化测试】Selenium IDE脚本编辑与操作
  • 杭电多校2023“钉耙编程”中国大学生算法设计超级联赛(5)
  • Matlab进阶绘图第24期—悬浮柱状图
  • 【题解】链表中倒数最后k个结点、删除链表的倒数第n个节点
  • 网络安全大厂面试题
  • 7.事件类型
  • ts中声明引入未使用的报错——解决方案
  • 集团MySQL的酒店管理系统
  • Kotlin基础(九):对象和委托
  • 八大排序算法--希尔排序(动图理解)
  • 数据结构之常见排序算法