当前位置: 首页 > 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静态代理与动态代理

 

相关文章:

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

代理模式 代理模式允许你为其他对象提供一个代理,以控制对这个对象的访问。代理模式在不改变实际对象的情况下,可以在访问对象时添加额外的功能。 可以理解为代理模式为被代理对象创造了一个替身,调用者可以通过这个替身去实现这个被代理对…...

Vue day02 Computed和Watch

1.事件绑定 可以用 v-on 指令监听DOM 事件&#xff0c;并在触发时运行一些 JavaScript 代码。v-on 还可以接收一个需要调用的方法名称。 <button v-on:click"handler">good</button> methods: { handler: function (event) { if (event) { alert(event.t…...

【Java】一只小菜坤的编程题之旅【3】

文章目录 1丶判定是否互为字符重排2、杨辉三角3丶某公司的1个面试题&#xff08;字符串包含问题&#xff09; 1丶判定是否互为字符重排 这个题我们用一个非常简单的思想就能实现&#xff0c;我们先将字符串转换为字符数组&#xff0c;然后对字符数组进行排序&#xff0c;然后再…...

全面掌握 Jaeger 分布式调用链路跟踪理论和实战,Go 为所有使用 go-resty 库发起 HTTP 请求集成链路跟踪 jaeger(附源码)

全面掌握 Jaeger 分布式调用链路跟踪理论和实战,Go 为所有使用 go-resty 库发起 HTTP 请求集成链路跟踪 jaeger(附源码)。 介绍一个开源的分布式跟踪系统 Jaeger,首先从理论基础知识开始学习,将学习如何在 HTTP 请求中集成链路跟踪,以及如何在 GORM 框架实现,最后学习 …...

vue键盘和鼠标事件

1、键盘事件 **按Enter键** keyup.enter**按PageDown键** keyup.page-down **按Tab键** keyup.tab **按Delete键** keyup.delete **按ESC键** keyup.esc**按Space键** keyup.space **按↑&#xff08;Up&#xff09;键** keyup.up**按↓&#xff08;Down&#xff09;键** keyup…...

Chrome 手动代理设置 HTTP/Socks5

1、安装代理插件&#xff1a;SwitchyOmega 在线安装 从 Chrome 应用商店 安装&#xff0c;如果您无法从该链接安装&#xff0c;请使用下面的离线安装。 离线安装 ①、去 Github 下载 最新版安装包 &#xff0c;或者直接 本地下载 文件进行安装。 ②、下载安装文件后&#xf…...

SpringBoot第35讲:SpringBoot集成连接池 - 默认连接池HikariCP

SpringBoot第35讲&#xff1a;SpringBoot集成连接池 - 默认连接池HikariCP 本文是SpringBoot第35讲&#xff0c;主要介绍数据库连接池&#xff0c;以及SpringBoot集成默认的HikariCP的实践。 文章目录 SpringBoot第35讲&#xff1a;SpringBoot集成连接池 - 默认连接池HikariCP1…...

选择最适合自己的笔记本

选择最适合自己的笔记本电脑 一、了解笔记本品牌一线品牌准一线品牌二线品牌三线品牌 二、笔记本入手渠道笔记本入手渠道 三、根据需求选择机型使用需求1.日常使用2.商务办公、财务3.轻度剪辑、ps4.代码5.创意设计6.游戏 四、笔记本电脑配置如何选1.cpu2.显卡&#xff08;GPU&a…...

前端安全:探秘安全 HTTP 头的设置

在当今数字化时代&#xff0c;前端安全至关重要。除了应对常见的攻击方式外&#xff0c;通过设置安全 HTTP 头&#xff0c;我们可以加强网站的安全性&#xff0c;减少潜在的威胁。本文将为您详细解释什么是安全 HTTP 头&#xff0c;以及如何通过设置它们来保护您的前端应用。 1…...

python爬虫——爬虫伪装和反“反爬”

前言 爬虫伪装和反“反爬”是在爬虫领域中非常重要的话题。伪装可以让你的爬虫看起来更像普通的浏览器或者应用程序&#xff0c;从而减少被服务器封禁的风险&#xff1b;反“反爬”则是应对服务器加强的反爬虫机制。下面将详细介绍一些常见的伪装和反反爬技巧&#xff0c;并提…...

vue3 使用 element-china-area-data 实现地区选择器

官方地址&#xff1a;https://www.npmjs.com/package/element-china-area-data?activeTabreadme 在线示例&#xff1a;https://plortinus.github.io/element-china-area-data/index.html 实际使用 <el-col :span"12"><el-form-item label"所处城市&…...

STM32自带的DSP库的滤波初体验(一)

最近在弄STM32自带的DSP库里的滤波&#xff0c;记录一下&#xff1a; arm_fir_instance_q15 instance_q15_S; #define NUM_TAPS 16 //滤波系数的个数 #define BLOCK_SIZE 32 q15_t firStateF32[BLOCK_SIZE NUM_TAPS]; q15_t Fir_Coeff[NUM_TAPS] {-79, -136, 312, 6…...

go kratos protobuf 接收动态JSON数据

前言 google.protobuf.Struct 是 Google Protocol Buffers 中的一种特殊类型&#xff0c;用于表示动态的键值对数据。它可以存储任意类型的数据&#xff0c;并提供了方便的方法来访问和操作这些数据。 Struct 类型通常用于在不事先知道数据结构的情况下传递和处理配置、参数或其…...

Python学习笔记第五十四天(Pandas DataFrame)

Python学习笔记第五十四天 Pandas 数据结构 - DataFrame使用列表创建使用 ndarrays 创建使用字典创建返回多行数 后记 Pandas 数据结构 - DataFrame DataFrame 是一个表格型的数据结构&#xff0c;它含有一组有序的列&#xff0c;每列可以是不同的值类型&#xff08;数值、字符…...

Docker镜像查看下载删除镜像文件的相关命令

1.镜像相关命令 本地查看有哪些镜像文件&#xff1a; docker images镜像的名称就是我们常见的一些软件&#xff0c;镜像相当于把软件和软件所需要的运行环境打包到一个镜像文件里面&#xff0c;将来在通过这个镜像文件创建出对应的容器&#xff0c;容器有了以后这些软件自动的…...

1. VisionOS平台介绍

介绍 VisionOS 可实现与现实世界无缝集成并与其他虚拟内容共存的 3D 多任务体验。这为个人生产力、生活方式和娱乐应用打开了一个充满新可能性的世界&#xff0c;并为开发人员打开了一个全新的市场。然而&#xff0c;它也带来了围绕多任务处理和与身体互动的新挑战。Unity Poly…...

【C#】设置有线网卡IP地址,子网掩码,网关,DNS

方法 public partial class ComputerInfo{/// <summary>/// 设置IP地址&#xff0c;子网掩码&#xff0c;网关&#xff0c;DNS/// </summary>public static List<NetworkAdapterInfo> SetIpAddressSubMaskDnsGeteway(string ipAddress, string subMask, stri…...

LVS-DR集群及NGINX负载均衡

LVS-DR集群 原理&#xff1a; 1. 当用户向负载均衡调度器&#xff08;Director Server&#xff09;发起请求&#xff0c;调度器将请求发往至内核空间 2. PREROUTING链首先会接收到用户请求&#xff0c;判断目标IP确定是本机IP&#xff0c;将数据包发往INPUT链 3. IPVS是工作在…...

React如何配置env环境变量

React版本&#xff1a; "react": "^18.2.0" 1、在package.json平级目录下创建.env文件 2、在‘.env’文件里配置环境变量 【1】PUBLIC_URL 描述&#xff1a;编译时文件的base-href 官方描述&#xff1a; // We use PUBLIC_URL environment variable …...

VR全景智慧文旅,用科技助力旅游业振兴

引言&#xff1a; 近年来&#xff0c;科技的迅猛发展将我们带入一个全新的数字化时代&#xff0c;而虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;技术则以其令人惊叹的全新方式&#xff0c;影响着各个领域。其中&#xff0c;旅游业作为人们探索世界、体…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...