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

Spring学习之——代理模式

Proxy代理模式

介绍

  1. 为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用

2. 组成

  • 抽象角色:通过接口或抽象类声明真实角色实现的业务方法。

    抽象角色一般声明为接口,内部写真实角色的抽象方法。
    eg.有一个公共的歌手接口,有一个唱歌的方法

  • 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

    eg.有一个类叫做周杰伦,实现了歌手的接口

  • 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。

    代理角色一般是来执行真实角色的方法以及自己所附加的方法。
    eg.有一个经纪人的类,他是来对接客户(实际调用者),他可以让周杰伦去唱歌,自己同时完成了面谈,签合同,订机票,收尾款等行为方法。

静态代理

1.抽象角色

package com.by.proxy.StaticProxy;public interface Star {/*** 面谈*/void confer();/*** 签合同*/void signContract();/*** 订票*/void bookTicket();/*** 唱歌*/void sing();/*** 收钱*/void collectMoney();
}

2.真正角色(周杰伦)

package com.by.proxy.StaticProxy;public class RealStar implements Star {public void bookTicket() {}public void collectMoney() {}public void confer() {}public void signContract() {}public void sing() {System.out.println("RealStar(周杰伦本人).sing()");}
}

3.代理角色(经纪人)

package com.by.proxy.StaticProxy;public class ProxyStar implements Star {private Star star;public ProxyStar(Star star) {super();this.star = star;}public void bookTicket() {System.out.println("ProxyStar.bookTicket()");}public void collectMoney() {System.out.println("ProxyStar.collectMoney()");}public void confer() {System.out.println("ProxyStar.confer()");}public void signContract() {System.out.println("ProxyStar.signContract()");}public void sing() {star.sing();}
}

4.测试

package com.by.proxy.StaticProxy;public class Client {public static void main(String[] args) {Star proxy = new ProxyStar(new RealStar());proxy.confer();proxy.signContract();proxy.bookTicket();proxy.sing();proxy.collectMoney();}
}

5.静态代理的缺点

  1. 代理类和实现类实现了相同的接口,这样就出现了大量的代码重复。
  2. 代理对象只服务于一种类型的对象。如果要服务多类型的对象,例如代码是只为UserService类的访问提供了代理,但是还要为其他类如DeptService类提供代理的话,就需要我们再次添加代理DeptService的代理类。

jdk动态代理

1.抽象角色

public interface Star {/*** 唱歌*/void sing();
}

2.真正角色(周杰伦)

package com.by.JdkProxy;//真实角色(周杰伦)
public class RealStar implements Star {//优点:此时代码不再重复public void sing() {System.out.println("周杰伦:快使用双截棍,哼哼哈嘿....");}
}

3.代理角色(经纪人)

package com.by.JdkProxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;//代理类工厂
public class ProxyFactory {//优点:此时可以代理任意类型的对象//真实角色(周杰伦)private Object realObj;public ProxyFactory(Object realObj) {this.realObj = realObj;}//获得代理对象public Object getProxyObject(){/*** Proxy:作用创建代理对象*      ClassLoader loader:类加载器*      Class<?>[] interfaces:真实角色实现的接口,根据接口生成代理类*      InvocationHandler h:增强的逻辑,即如何代理(宋吉吉要做的事)*/return Proxy.newProxyInstance(realObj.getClass().getClassLoader(),realObj.getClass().getInterfaces(),new InvocationHandler() {/**** @param proxy:代理类,一般不用* @param method:要调用的方法* @param args:调用方法时的参数* @return* @throws Throwable*/public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("真正的方法执行前!");System.out.println("面谈,签合同,预付款,订机票");Object result = method.invoke(realObj, args);System.out.println("真正的方法执行后!");System.out.println("收尾款");return result;}});}
}

4.测试

public class Client {public static void main(String[] args) {//获得代理对象Star proxyObject = (Star) new ProxyFactory(new RealStar()).getProxyObject();System.out.println(proxyObject.getClass());//class com.sun.proxy.$Proxy0proxyObject.sing();}
}

Cglib动态代理

cglib与动态代理最大的区别就是:

  • 使用jdk动态代理的对象必须实现一个接口
  • 使用cglib代理的对象则无需实现接口

CGLIB是第三方提供的包,所以需要引入jar包的坐标:

<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>2.2.2</version>
</dependency>

如果你已经有spring-core的jar包,则无需引入,因为spring中包含了cglib。

1.真正角色

package com.by.proxy.CglibProxy;public class RealStar{public void sing() {System.out.println("RealStar(周杰伦本人).sing()");}
}

2.代理角色(经纪人)

package com.by.proxy.CglibProxy;import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;//代理工厂
public class ProxyFactory implements MethodInterceptor {//真实角色private Object realObj;public ProxyFactory(Object realObj) {this.realObj = realObj;}/**'* 获得子类代理对象* @return*/public Object getProxyObject() {//工具类Enhancer en = new Enhancer();//设置父类en.setSuperclass(realObj.getClass());//设置回调函数en.setCallback(this);//创建子类代理对象return en.create();}/*在子类中调用父类的方法intercept方法参数说明:obj : 代理对象method : 真实对象中的方法的Method实例args : 实际参数methodProxy :代理对象中的方法的method实例*/public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy)throws Throwable {System.out.println("真正的方法执行前!");System.out.println("面谈,签合同,预付款,订机票");Object result = method.invoke(realObj, args);System.out.println("真正的方法执行后!");System.out.println("收尾款");return object;}
}

3.测试

package com.by.proxy.CglibProxy;//测试类
public class Client {public static void main(String[] args) {//获取代理对象RealStar proxyObject = (RealStar) new ProxyFactory(new RealStar()).getProxyObject();proxyObject.sing();}
}

AOP中的代理

  1. 切点对应的是真实角色的方法
  2. 增强对应的是抽象角色,创建了真实角色的代理类,不仅执行了真实角色的方法,还加入了自己的方法(前置通知,后置通知,异常通知,环绕通知,最终通知)

相关文章:

Spring学习之——代理模式

Proxy代理模式 介绍 为其他对象提供一种代理以控制对这个对象的访问。在某些情况下&#xff0c;一个对象不适合或者不能直接引用另一个对象&#xff0c;而代理对象可以在客户端和目标对象之间起到中介的作用 2. 组成 抽象角色&#xff1a;通过接口或抽象类声明真实角色实现的…...

【Linux】之搭建 PostgreSQL 环境

前言 在 Linux 系统下安装 PostgreSQL&#xff0c;可以选择快捷方便的 Docker 安装&#xff0c;但正常的服务器都是直接原生安装的&#xff0c;所以&#xff0c;这里我将讲解如何正常安装 PostgreSQL 以及安装之后的一些配置。如果想了解 Docker 安装的话&#xff0c;可以查看我…...

docker 安装elasticsearch、kibana、cerebro、logstash

安装步骤 第一步安装 docker 第二步 拉取elasticsearch、kibana、cerebro、logstash 镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.10.2 docker pull docker.elastic.co/kibana/kibana:7.10.2 docker pull lmenezes/cerebro:latest docker pull l…...

C/C++ 联合体

目录 联合体概述 联合体的内存分配 联合体大小计算 联合体概述 联合与结构非常的相似&#xff0c;主要区别就在于联合这两个字。 联合的特征&#xff1a;联合体所包含的成员变量使用的是同一块空间。 联合体定义 //联合类型的声明 union Un {char c;int i; }; //联合变量…...

基于SSM的基金投资交易管理网站的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…...

JS数据类型转换成Boolean型

在javaScript中 布尔值用到的很频繁 接下来让我稍微为大家介绍一下数据类型转换为布尔型 转换成布尔值为false的类型 console.log(Boolean("")) //falseconsole.log(Boolean(0)) //falseconsole.log(Boolean(undefined)) //falseconsole.log(Boolean(null)) //false…...

uni-app页面数据传参方式

uni-app 是一个使用 Vue.js 开发所有前端应用的框架&#xff0c;可以编译到 iOS、Android、H5、小程序等多个平台。当你在多个页面间传递参数时&#xff0c;通常有多种方法&#xff0c;例如通过 uni.navigateTo、路由参数、本地存储等方式。下面是一些方法的说明和示例代码。 …...

计算机网络实验(二):Wireshark网络协议分析

一、实验名称&#xff1a;Wireshark网络协议分析 二、实验原理 HTTP协议分析 1.超文本传输协议&#xff08;Hypertext Transfer Protocol, HTTP&#xff09;是万维网&#xff08;World Wide Web&#xff09;的传输机制&#xff0c;允许浏览器通过连接Web服务器浏览网页。目…...

Spark内核解析-数据存储5(六)

1、Spark的数据存储 Spark计算速度远胜于Hadoop的原因之一就在于中间结果是缓存在内存而不是直接写入到disk&#xff0c;本文尝试分析Spark中存储子系统的构成&#xff0c;并以数据写入和数据读取为例&#xff0c;讲述清楚存储子系统中各部件的交互关系。 1.1存储子系统概览 …...

ASP.NET Core高级之认证与授权(一)--JWT入门-颁发、验证令牌

阅读本文你的收获 了解认证和授权的作用了解在ASP.NET Core中实现身份认证的技术都有哪些学习基于JWT认证并学会颁发和验证JWT令牌 一、重要的前置概念 在一个系统中&#xff0c;不是所有的功能和资源都能够被自由地访问&#xff0c;比如你存在银行系统里面的资金&#xff0c…...

实例:NodeJS 操作 Kafka

本人是C#出身的程序员&#xff0c;c#很简单就能实现&#xff0c;有需要的可以加我私聊。但是就目前流行的开发语言&#xff0c;尤其是面向web方向应用的&#xff0c;我感觉就是Nodejs最简单了。下面介绍&#xff1a; 本文将会介绍在windows环境下启动Kafka&#xff0c;并通过n…...

AI实景无人直播创业项目:开启自动直播新时代,一部手机即可实现增长

在当今社会&#xff0c;直播已经成为了人们日常生活中不可或缺的一部分。无论是商家推广产品、明星互动粉丝还是普通人分享生活&#xff0c;直播已经渗透到了各行各业。然而&#xff0c;传统直播方式存在着一些不足之处&#xff0c;如需现场主持人操作、高昂的费用等。近年来&a…...

YOLOv5改进 | 损失函数篇 | InnerIoU、InnerSIoU、InnerWIoU、FocusIoU等损失函数

一、本文介绍 本文给大家带来的是YOLOv5最新改进,为大家带来最近新提出的InnerIoU的内容同时用Inner的思想结合SIoU、WIoU、GIoU、DIoU、EIOU、CIoU等损失函数,形成 InnerIoU、InnerSIoU、InnerWIoU等新版本损失函数,同时还结合了Focus和AIpha思想,形成的新的损失函数,其…...

构建高效PythonWeb:GraphQL+Sanic

1.1 简介&#xff1a;在当今快速发展的技术时代&#xff0c;Web应用的性能和灵活性变得越来越重要。在众多技术中&#xff0c;GraphQL和Sanic以其独特的优势脱颖而出。GraphQL&#xff0c;作为一个强大的数据查询语言&#xff0c;为前端和后端之间的通信提供了极大的灵活性。而…...

【通义千问】大模型Qwen GitHub开源工程学习笔记(5)-- 模型的微调【全参数微调】【LoRA方法】【Q-LoRA方法】

摘要: 训练数据的准备 你需要将所有样本放到一个列表中并存入json文件中。每个样本对应一个字典,包含id和conversation,其中后者为一个列表。示例如下所示: [{"id": "identity_0","conversations": [{"from": "user",…...

PCL 大地坐标转空间直角坐标(C++详细过程版)

目录 一、算法原理二、代码实现三、结果展示四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT生成的文章。 一、算法原理 二、代码实现 头文件及读取保存函数见:PCL 空间直角坐标转大地坐标(直接求解法C…...

Linux之Shell编程

shell是什么 shell是一个命令行解释器&#xff0c;他为用户提供一个向linux内核发送请求以便运行程序的界面系统级程序&#xff0c;用户可以用shell来启动&#xff0c;挂起&#xff0c;停止甚至编写一些程序。 shell脚本的执行方式 脚本格式要求 脚本以#!/bin/bash开头脚本需…...

Unity组件开发--传送点

本组件仅实现A传送点到B传送的功能&#xff0c;是可以双向传送的&#xff0c;如果只要单向传送&#xff0c;可以另外改脚本实现&#xff1b; 先看效果&#xff1a; unity组件传送点演示 1.传送组件shader是怎么写的&#xff1a;这种效果的实现方案 shader编辑器是这样的&#…...

vue结合Cesium加载gltf模型

Cesium支持什么格式&#xff1f; Cesium支持的格式包括&#xff1a;3D模型格式&#xff08;如COLLADA、gITF、OBJ&#xff09;、影像格式&#xff08;如JPEG、PNG、GeoTIFF&#xff09;、地形格式&#xff08;如STL、Heightmap&#xff09;、矢量数据格式&#xff08;如GeoJSON…...

逆置算法和数组循环移动算法

元素逆置 概述&#xff1a;其实就是将 第一个元素和最后一个元素交换&#xff0c;第二个元素和倒数第二个元素交换&#xff0c;依次到中间位置。用途&#xff1a;可用于数组的移动&#xff0c;字符串反转&#xff0c;链表反转操作&#xff0c;栈和队列反转等操作。 逆置图解 …...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...