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

Java代理模式——静态代理与动态代理

代理模式

代理模式允许你为其他对象提供一个代理,以控制对这个对象的访问。代理模式在不改变实际对象的情况下,可以在访问对象时添加额外的功能。

可以理解为代理模式为被代理对象创造了一个替身,调用者可以通过这个替身去实现这个被代理对象的功能,这个替身也可以为被代理对象增加功能

静态代理

定义

使用时候需要定义接口或者父类。 代理类和委托类有共同的父类或父接口。

案例

首先定义一个接口 ITeacherDao,并在这个接口中定义一个teacher()方法。

package Static;public interface ITeacherDao {void teacher();
}

再写一个他的实现类,实现teacher()方法

package Static;public class TeacherDao implements ITeacherDao{@Overridepublic void teacher() {System.out.println("老师在教课");}
}

 如上,我们实现了一个简单接口与他的实现类,接下来我们实现一个老师的静态代理类

package Static;public class TeacherDaoProxy implements ITeacherDao{private TeacherDao teacherDao;public TeacherDaoProxy(TeacherDao teacherDao){this.teacherDao = teacherDao;}@Overridepublic void teacher() {System.out.println("代理前");teacherDao.teacher();System.out.println("代理后");}
}

在这段代码中,我们实现了TeacherDao的代理类,并通过调用teacherDao这个对象使用了被代理对象的方法;我们在使用被代理对象方法前后都拓展了新的功能,这就是静态代理。

下面是主函数对于静态代理的使用

public class Main {public static void main(String[] args) {Static.TeacherDao teacherDao = new TeacherDao();TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);teacherDaoProxy.teacher();}
}

195c117885ca4f15b6cd8463aa19f3fe.png

 这说明我们的代理类在实现被代理对象的功能时也拓展了新的功能

但是,这样的模式也存在一种缺陷,就是我们的代理对象和被调用对象都要实现同一接口或父类,可能会出现多个代理类,接口如果要增加方法的话会有很多代理类需要维护;针对这一问题,Java的开发者定义了相关方法去解决,这就是我们下面要介绍的被代理类。

动态代理

定义

不需要实现接口,但是被代理的目标对象需要实现,调用jdk的api形成代理对象,

动态代理就是通过使用反射,动态地获取抽象接口的类型,从而获取相关特性进行代理。

案例

我们还是先定义一个接口

public interface ITeacherDao {void teacher();void sayhello();
}

接着我们定义他的实现类

public class TeacherDao implements ITeacherDao {@Overridepublic void teacher() {System.out.println("老师在教课");}@Overridepublic void sayhello() {System.out.println("hello");}
}

接着我们实现一个动态的代理类,可以动态代理原对象;在这个代理类中,我们使用到了Proxy.newProxyInstance 这个函数,他有三个参数,以下是三个参数的解释

1.target.getClass().getClassLoader():获取被代理对象的类加载器。这是用于加载代理类的类加载器。

2.target.getClass().getInterfaces():获取被代理对象实现的接口。这些接口是代理类将要实现的接口。

3.new InvocationHandler() { ... }:创建一个匿名的 InvocationHandler 对象,它实现了 invoke 方法,这是代理逻辑的核心部分。

 我们在InvocationHandler() { ... }中调用了被代理对象的方法,并且做了一些扩展

public class FactoryProxy  {private Object target;public FactoryProxy(Object target){this.target = target;}public Object getProxyIstance() {return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("代理前");Object returnVal = method.invoke(target,args);System.out.println("代理后");return returnVal;}});};
}

在主函数中调用被代理类,创建一个接口类,讲接口类传入被代理类,然后就可以定义接口类中的方法了,即实现了动态代理。

public class Main {public static void main(String[] args) {ITeacherDao iteacherDao = new TeacherDao();ITeacherDao proxyInstance = (ITeacherDao) new FactoryProxy(iteacherDao).getProxyIstance();proxyInstance.teacher();proxyInstance.sayhello();}
}

最终输出结果

16a5868de5f44169a1e57c0dd9d84054.png

 可以看出,我们通过动态代理类实现了对目标对象的功能拓展

链接

java静态代理与动态代理: java静态代理与动态代理

 

http://www.lryc.cn/news/122457.html

相关文章:

  • Vue day02 Computed和Watch
  • 【Java】一只小菜坤的编程题之旅【3】
  • 全面掌握 Jaeger 分布式调用链路跟踪理论和实战,Go 为所有使用 go-resty 库发起 HTTP 请求集成链路跟踪 jaeger(附源码)
  • vue键盘和鼠标事件
  • Chrome 手动代理设置 HTTP/Socks5
  • SpringBoot第35讲:SpringBoot集成连接池 - 默认连接池HikariCP
  • 选择最适合自己的笔记本
  • 前端安全:探秘安全 HTTP 头的设置
  • python爬虫——爬虫伪装和反“反爬”
  • vue3 使用 element-china-area-data 实现地区选择器
  • STM32自带的DSP库的滤波初体验(一)
  • go kratos protobuf 接收动态JSON数据
  • Python学习笔记第五十四天(Pandas DataFrame)
  • Docker镜像查看下载删除镜像文件的相关命令
  • 1. VisionOS平台介绍
  • 【C#】设置有线网卡IP地址,子网掩码,网关,DNS
  • LVS-DR集群及NGINX负载均衡
  • React如何配置env环境变量
  • VR全景智慧文旅,用科技助力旅游业振兴
  • 系统架构设计专业技能 · 系统安全分析与设计(四)【加解密、数字信封、信息摘要、数字签名、数字书证、网络安全、信息安全】
  • 基于WebSocket的在线文字聊天室
  • VS Code中C++程序的调试(Debug)功能
  • C#四个字节十六进制与单精度浮点数互转
  • Springloc和aop的基础概念
  • 算法练习Day43|● 518. 零钱兑换 II ● 377. 组合总和 Ⅳ
  • 人类:我觉得1+1=956446,你觉得呢?大模型:啊对对对
  • Offset Explorer
  • 查看CentOS版本及系统位数与设置CentOS 7.9 2009 防火墙配置放开端口的命令与过程
  • 前端css高级
  • 华为OD真题--字符串中最小的整数和--带答案