设计模式——代理模式

devtools/2024/9/24 19:13:51/

静态代理

例子:有一个教师类,教师类有一个教书方法
需要使用一个代理类来代理教师,将教师类聚合到代理类里面
在这里插入图片描述
具体代码如下:
首先创建一个接口,不仅教师类需要实现,代理类也需要实现,但是注意的是,代理类实现的时候,是使用的教师类的教书方法。

package com.StaticProxy;//代理模式
public interface ITeacherDao {void teach();
}
package com.StaticProxy;//真正的实体对象,需要被代理的类
//该类中有真正的教书方法
public class TeacherDao implements ITeacherDao {private String name;public void setName(String name) {this.name = name;}@Overridepublic void teach() {System.out.println(this.name + "在教书");}
}
package com.StaticProxy;//代理,需要代理TeacherDao,它虽然有teach方法,但是不是真的会教书,所以需要调用TeacherDao的教书方法
public class TeacherDaoProxy implements ITeacherDao{private ITeacherDao teacherDao;public TeacherDaoProxy(ITeacherDao teacherDao) {this.teacherDao = teacherDao;}@Overridepublic void teach() {System.out.println("通过代理对象。。。");System.out.println("代理使用真实的teacherDao在教书");teacherDao.teach();System.out.println("代理结束");}
}

使用代理类:

package com.StaticProxy;public class Client {public static void main(String[] args) {//新建一个TeacherDAO类TeacherDao teacherDao = new TeacherDao();teacherDao.setName("lisi");//使用一个代理类来代理教师类TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);teacherDaoProxy.teach();}
}

因为是静态代理,所以就是教师代理类,要是换一个需要代理的类,就不能实现了。一次引入动态代理。

动态代理

使用一个proxyFactory,传入一个Target目标对象,动态生成对应的目标代理对象。

在这里插入图片描述
首先需要一个目标对象类的接口。

package com.DynamicProxy;public interface ITeacherDao {void teach();
}

目标对象类实现这个接口。

package com.DynamicProxy;public class TeacherDao implements ITeacherDao{private String name;public void setName(String name) {this.name = name;}@Overridepublic void teach() {System.out.println(this.name + "在教书");}
}

动态代理工厂
在该类中,使用Proxy.newProxyInstance,生成代理对象,这个方法有3个参数:

  1. ClassLoader loader :当前目标对象使用的类加载器,获取加载器的方法固定
  2. Class<?>[] interfaces:目标对象实现的接口类型,使用泛型方法确定类型
  3. InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器方法,会把当前执行的目标对象方法作为一个参数传入
package com.DynamicProxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class ProxyFactory {//维护一个目标对象,object  这里相当于TeacherDao了private Object target;//构造器,对target进行初始化public ProxyFactory(Object target){this.target = target;}//给目标对象 生成一个代理对象//    ClassLoader loader :当前目标对象使用的类加载器,获取加载器的方法固定
//    Class<?>[] interfaces:目标对象实现的接口类型,使用泛型方法确定类型
//    InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器方法,会把当前执行的目标对象方法作为一个参数传入public Object getProxyInstance(){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("jdk代理开始---");//反射机制调用目标对象的方法Object returnVal = method.invoke(target, args);return returnVal;}});}
}
package com.DynamicProxy;import com.DynamicProxy.TeacherDao;public class Client {public static void main(String[] args) {//目标对象
//        ITeacherDao teacherDao = new TeacherDao();TeacherDao teacherDao = new TeacherDao();teacherDao.setName("lisi");//使用代理工厂 给目标对象创建代理对象ProxyFactory proxyFactory = new ProxyFactory(teacherDao);//强转成ITeacherDao类型 否则没办法调用教书方法ITeacherDao proxyInstance =(ITeacherDao) proxyFactory.getProxyInstance();//proxyInstance : class com.sun.proxy.$Proxy0 内存中动态生成了代理对象proxyInstance.teach();}
}

http://www.ppmy.cn/devtools/5491.html

相关文章

Matlab之空间坐标系绘制平面图形

在空间直角坐标系中&#xff0c;绘制指定平面方程的图形 版本说明&#xff1a; 20240413_V1.01&#xff1a;更正代码错误&#xff0c;并修改输入参数类型&#xff08;测试用例得修改&#xff09; 20240413_V1.00&#xff1a;初始版本 一、平面方程 基本形式为&#xff1a;A…

rust基础

RUST编程基础 编程概念rust编程概念变量可变性变量遮蔽语句和表达式所有权生命周期Self和self错误处理注释变量声明顺序问题 数据类型基本类型整数类型序列字符/布尔/单元类型 其他类型字符串和切片字符串切片 结构体枚举类型数组元组引用函数方法泛型和特征泛型特征特征对象 复…

Android JNI使用dlopen动态链接库

dlopen 是一个用于在系统中动态加载共享库&#xff08;动态链接库&#xff09;的函数。它的主要作用是在程序运行时动态地加载共享库&#xff0c;使得程序可以在不重新编译的情况下加载并使用库中的函数和变量。 具体来说&#xff0c;dlopen 函数可以接受一个共享库的路径作为…

前端常用的数据加密方式

前端开发中&#xff0c;数据安全是至关重要的一个方面。数据加密是保护用户隐私和信息安全的关键方法之一。 前端常用的数据加密方式涵盖了对传输数据的加密、存储数据的加密以及客户端与服务器端之间通信的加密。 1. 对称加密算法 对称加密算法使用相同的密钥进行加密和解密…

Keepalived+LVS+nginx搭建nginx高可用集群

一、简介 nginx是一款非常优秀的反向代理工具&#xff0c;支持请求分发&#xff0c;负载均衡&#xff0c;以及缓存等等非常实用的功能。在请求处理上&#xff0c;nginx采用的是epoll模型&#xff0c;这是一种基于事件监听的模型&#xff0c;因而其具备非常高效的请求处理效率…

写一个uniapp的登录注册页面

目录 一、效果图 二、代码 1、登录 &#xff08;1&#xff09;页面布局代码 &#xff08;2&#xff09;逻辑实现代码 &#xff08;3&#xff09;css样式 2、注册 &#xff08;1&#xff09;页面布局代码 &#xff08;2&#xff09;逻辑实现代码 &#xff08;3&#x…

Webpack 5配置详解与性能优化技巧

Webpack 5是一款非常流行的前端打包工具&#xff0c;它可以帮助我们将多个前端资源&#xff08;如JS、CSS、图片等&#xff09;打包成一个或多个静态资源文件。在使用Webpack 5时&#xff0c;我们可以通过配置文件来定制打包的方式和过程&#xff0c;同时也可以通过一些优化技巧…

Qt——【若按钮点击后无反应,UI界面中已经勾选Checkable属性, 并且调用了按钮的setchecked(false), 但是页面就是不切换状态

几经排查&#xff0c;发现是按钮组的Exclusive属性造成的。Exclusive属性执行后&#xff0c; 当有一个选中&#xff0c;并且没有选择其它按钮时&#xff0c;此按钮一直为选中状态。即使执行了按钮的setchecked&#xff08;false&#xff09;。 如果QAbstractButton属于独占组&a…