当前位置: 首页 > 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;栈和队列反转等操作。 逆置图解 …...

【MATLAB】数豆子

Matlab数豆子 创建一个变量来表示豆子的数量。例如&#xff0c;可以使用豆子数量 100;来表示有100颗豆子。 使用disp函数打印出豆子的数量。例如&#xff0c;可以使用disp([目前有 num2str(豆子数量) 颗豆子])来打印出当前豆子的数量。 进行豆子的计数操作。例如&#xff0c…...

QT C++中调用python脚本时,import第三方库失败问题解决

QT C中调用python脚本时&#xff0c;import第三方库失败问题解决 文章目录 QT C中调用python脚本时&#xff0c;import第三方库失败问题解决前言一、问题复现二、调试过程三、问题解决1 numpy问题解决2 matplotlib问题解决 四、补充说明五、参考资料 前言 项目需要&#xff0c…...

【AI视野·今日Robot 机器人论文速览 第七十期】Thu, 4 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Thu, 4 Jan 2024 Totally 17 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Many-Objective-Optimized Semi-Automated Robotic Disassembly Sequences Authors Takuya Kiyokawa, Kensuke Harada, Weiwei …...

Flutter中的布局组件介绍及使用

1. 引言 Flutter 是一款由 Google 开发的开源 UI 软件开发工具&#xff0c;可用于在单个代码库中构建漂亮、本机编译的应用程序。在 Flutter 中&#xff0c;布局是构建用户界面的核心部分之一。本文将介绍 Flutter 中的全部布局组件&#xff0c;以及它们的使用方式。 2. 基础…...

【面试高频算法解析】算法练习2 回溯(Backtracking)

前言 本专栏旨在通过分类学习算法&#xff0c;使您能够牢固掌握不同算法的理论要点。通过策略性地练习精选的经典题目&#xff0c;帮助您深度理解每种算法&#xff0c;避免出现刷了很多算法题&#xff0c;还是一知半解的状态 专栏导航 二分查找回溯&#xff08;Backtracking&…...

认识Git

&#x1f30e;初识Git 初识Git 什么是Git Git的安装       Centos平台安装Git       Ubuntu平台安装Git Git的基本操作       创建远程仓库       配置Git 认识工作区、暂存区与版本库       添加文件到暂存区       将暂存区文件提交至本…...

@RequestParam,@RequestBody和@PathVariable 区别

RequestParam&#xff0c;RequestBody和PathVariable 这三者是spring常见的接受前端数据的注解&#xff0c;那么他们分别是接受什么的前端数据呢&#xff1f; RequestParam&#xff1a;这个注解主要用于处理请求参数&#xff0c;尤其是GET请求中的查询参数和表单参数。它可以用…...

vue3组件传参

1、props: 2、自定义事件子传父 3、mitt任意组件通讯 4、v-model通讯(v-model绑定在组件上) (1)V2中父子组件的v-model通信&#xff0c;限制了popos接收的属性名必须为value和emit触发的事件名必须为input,所以有时会有冲突; 父组件: 子组件: (2)V3中:限制了popos接收的属性名…...

React16源码: React中创建更新的方式及ReactDOM.render的源码实现

React当中创建更新的主要方式 ReactDOM.render || hydrate 这两个API都是我们要把整个应用第一次进行渲染到我们的页面上面能够展现出来我们整个应用的样子的一个过程这是初次渲染 setState 后续更新应用 forceUpdate 后续更新应用 replaceState 在后续被舍弃 关于 ReactDOM…...

CentOS 7 系列默认的网卡接口名称

CentOS 7 系列默认的网卡接口是随机的&#xff0c;如果要修改网卡名称以 eth 开头&#xff0c;有两种方式。 方法一&#xff1a;安装系统时 在安装界面移动光标到 Install Centos 7.按 TAB 键 在出现的代码的末尾添加&#xff1a;net.ifnames0 biosdevname0.按下回车开始安装即…...

山东枣庄滕州网站建设/百度网盘资源搜索引擎

搬寝室 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8907 Accepted Submission(s): 2996 Problem Description搬寝室是很累的,xhd深有体会.时间追述2006年7月9号,那天xhd迫于无奈要从27号楼搬到3号楼,因为10…...

网站开发软件技术开发公司/百度灰色关键词排名推广

一、 Collections算法类 它是一个工具类/帮助类&#xff0c;其中提供了一系列静态方法&#xff0c;用于对集合中元素进行排序、搜索以及线程安全等各种操作。 格式&#xff1a;Collections.方法名() 就如数组的操作类Arrays类一样&#xff0c;Collections类是一个操作集合…...

dw制作网站模板/百度app下载最新版

第一部分、什么是动态规划算法 ok&#xff0c;咱们先来了解下什么是动态规划算法。 动态规划一般也只能应用于有最优子结构的问题。最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足&#xff0c;故有时需要引入一定的近似)。简单地说&#xf…...

出台网站集约化建设通知/做网站价格

区别&#xff1a; #系统级环境配置文件 /etc/profile /etc/bashrc#用户级环境配置文件 ~/.bashrc ~/.profile/etc/profile: 用来设置系统环境参数&#xff0c;比如$PATH. 这里面的环境变量是对系统内所有用户生效的。 /etc/bashrc: 这个文件设置系统bash shell相关的东西&a…...

wordpress 后台主题/免费永久注册顶级域名网站

http://blog.csdn.net/leagoal/article/details/5705094...

广州网站建设十年乐云seo/免费注册个人网站不花钱

最近雷卯电子EMC工程师接到很多同学关于液晶屏ESD失效的整改案例&#xff0c;其实非常建议电子工程师在设计时考虑esd防护&#xff0c;这里做一个科普。 1静电的产生 静电是一种客观存在的自然现象&#xff0c;产生的方式多种&#xff0c;如接触、摩擦、电器间感应等。静电的特…...