Spring AOP基于动态代理的实现的 AOP

目录

  • 代理
    • 什么是代理
    • 代理模式
  • 静态代理
  • 动态代理
    • JDK动态代理
    • CGLIB动态代理
    • Spring AOP使用的是哪种代理?

代理

什么是代理

生活中的代理

  • 房产中介 : 房屋进行租赁时,卖方会把房子授权给中介,由中介代理带客户看房,商谈价格
  • 艺人经纪人:广告商找艺人拍广告时,不会直接和艺人沟通,会和经纪人沟通
    房子的主人要做的事情,交给中介代理

代理模式

代理模式(菜鸟教程)

为其他对象提供一种代理以控制这个对象的访问,它的作用就是通过一个代理类,让我们在调用目标方法的时候,不是直接对目标得到进行调用,而是通过代理间接调用

代理模式的主要角色

  1. Subject: 业务接口类,可以是抽象类或者接口(不一定有)
  2. RealSubject: 业务实现类,具体的业务执行,也就是被代理对象
  3. Proxy: 代理类.RealSubjectde的代理

比如说房屋这里
Subject:提前定义好的事情,交给中介做的事情。
RealSubject:房东
Proxy:中介

根据代理的创建时期,代理模式分为静态代理和动态代理。

静态代理

由程序员创建代理类或特定工具自动生成源代码在对其编译,在程序员运行前代理类的.class文件就已经存在了
(在出租房子之前,中介已经做好了相关的工作,就等用户来租房子了)

  1. 定义接口(定义房东要做的事情,也是中介需要做的事情)
   public interface HouseSubject {void rentHouse();
}
  1. 实现接口(房东出租房子)
public class RealHouseSubject implements HouseSubject{@Overridepublic void rentHouse() {System.out.println("我是房东,我出租房子");}
}
  1. 代理(中介,帮房东)
public class HouseProxy implements HouseSubject{//将被代理对象是声明为成员变量private HouseSubject houseSubject;public HouseProxy(HouseSubject houseSubject) {this.houseSubject = houseSubject;}@Overridepublic void rentHouse() {// 开始代理System.out.println("我是中介,开始代理");//代理房东出租房子houseSubject.rentHouse();//代理结束System.out.println("代理结束");}
}

4.使用

public class StaticMain {public static void main(String[] args) {HouseSubject subject = new RealHouseSubject();//创建代理类HouseProxy proxy = new HouseProxy(subject);//通过代理类访问目标方法proxy.rentHouse();}
}

运行结果

在这里插入图片描述

虽然静态代理完成了对目标对象的代理,但是由于代码都写死了,对目标对象的每个方法的增强都是手动完成的,非常不灵活

如果增加需求:代理房屋出售

1.定义接口修改

public interface HouseSubject {void rentHouse();void saleHouse();
}

2.接口实现修改

public class RealHouseSubject implements HouseSubject{@Overridepublic void rentHouse() {System.out.println("我是房东,我出租房子");}@Overridepublic void saleHouse() {System.out.println("我是房东,我出售房子");}
}

3.代理类修改


public class HouseProxy implements HouseSubject{//将被代理对象是声明为成员变量private HouseSubject houseSubject;public HouseProxy(HouseSubject houseSubject) {this.houseSubject = houseSubject;}@Overridepublic void rentHouse() {// 开始代理System.out.println("我是中介,开始代理");//代理房东出租房子houseSubject.rentHouse();//代理结束System.out.println("代理结束");}@Overridepublic void saleHouse() {// 开始代理System.out.println("我是中介,开始代理");//代理房东出售房子houseSubject.saleHouse();//代理结束System.out.println("代理结束");}
}

我们修改接口(Subject)和业务实现类(RealSubject)时,还需要修改代理类(Proxy)。
同样的,如果有新增接口(Subject)和业务实现类(RealSubject),也需要对每一个业务实现类新增代理类(Proxy)

代理的流程是一样的,有没有一种办法,让他们通过一个代理类来实现呢?
这就需要用到动态代理技术了

动态代理

在程序运行时,运用发射制动态创建而成
(对于房子中介,我们不需要提前预测都有哪些业务,而是业务来了,在根据情况创建)

JDK动态代理

1.定义一个接口及其实现类(静态代理中的HouseSubject 和 RealHouseSubject)
2.自定义InvocationHandler并重写invoke方法,在invoke方法中我们会调用目标方法(被代理类的方法)并自定义一些处理逻辑
3.通过Proxy.newPorxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) 方法创建代理对象

Loader:类加载器,用于加载代理对象
interfaces:被代理类实现的一些接口(这个参数的定义,也决定了JDK动态代理只能实现了接口的一些类)
h:实现了InvocationHandler接口对象

CGLIB动态代理

JDK动态代理有一个最致命的问题是其只能实现接口类。
在有一些场景下,我们的业务代码是直接实现的,并没有接口定义,CGLIB动态代理机制这时派上用场。

CGLIB介绍与原理

CGLIB是一个开源项目,需要手动添加相关依赖

<dependency><groupId>cglib</groupId><artifactId>cglib-nodep</artifactId><version>3.1</version></dependency>

Spring AOP使用的是哪种代理?

1.Spring Framework
2.Speing Boot
底层实现都是JDK和CGLIB
Spring Framework: 如果代理的是接口,使用JDK。 如果代理的是没有实现接口的类,使用CGLIB

在这里插入图片描述
Spring Boot:默认配置使用CGLIB代理 在Spring Boot 2.X 之后的版本代理无论是否实现了接口,都使用CGLIB代理,如果需要使用JDK代理,需要设置。在Spring Boot 2.X 之前的版本默认使用JDK代理(和Spring Framework一致)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/17550.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计师可以学什么程序编程

设计师可以学什么程序编程 在数字化日益发展的今天&#xff0c;设计师们不仅需要具备出色的创意和设计能力&#xff0c;同时掌握一定的程序编程技能也变得越来越重要。这不仅可以帮助设计师更好地将创意转化为实际产品&#xff0c;还能提高工作效率&#xff0c;拓宽职业发展空…

枚举(C语言)

1.枚举定义 枚举是 C 语言中的一种基本数据类型&#xff0c;用于定义一组具有离散值的常量&#xff0c;它可以让数据更简洁&#xff0c;更易读。 枚举类型通常用于为程序中的一组相关的常量取名字&#xff0c;以便于程序的可读性和维护性。 定义一个枚举类型&#xff0c;需要使…

行为型设计模式之模板模式

文章目录 概述原理结构图实现 小结 概述 模板方法模式(template method pattern)原始定义是&#xff1a;在操作中定义算法的框架&#xff0c;将一些步骤推迟到子类中。模板方法让子类在不改变算法结构的情况下重新定义算法的某些步骤。 模板方法中的算法可以理解为广义上的业…

Function Calling学习

Function Calling第一篇 Agent&#xff1a;AI 主动提要求Function Calling&#xff1a;AI 要求执行某个函数场景举例&#xff1a;明天上班是否要带伞&#xff1f;AI反过来问你&#xff0c;明天天气怎么样&#xff1f; Function Calling 的基本流程 Function Calling 完整的官…

北斗高精度定位终端的工作原理和精度范围

北斗高精度定位终端的工作原理主要基于北斗卫星导航系统&#xff0c;通过卫星信号的接收、处理和计算&#xff0c;实现了对目标位置的精确测量。以下是关于北斗高精度定位终端工作原理的引文&#xff1a; ​ 北斗高精度定位终端作为一款新型的高精定位设备&#xff0c;其核心…

使用uniapp内置组件checkbox-group所遇到的问题

checkbox-group属性说明 属性名类型默认值说明changeEventHandle <checkbox-group> 中选项发生改变触发change事件 detail { value&#xff1a;[选中的checkbox的value的数组] } 问题代码 <checkbox-group change"handleEVent()"><view style&qu…

python2.7安装M2Crypto

对于Python 2.7安装M2Crypto&#xff0c;你可以按照以下步骤进行&#xff1a; 环境准备 操作系统&#xff1a;根据你的操作系统&#xff08;如macOS、Windows等&#xff09;&#xff0c;你需要确保你的Python 2.7环境已经正确设置。 依赖库&#xff1a; SWIG&#xff1a;M2Cry…

pg_lakehouse 与 datafusion

原理分析 pg_lakehouse 是 ParadeDB 推出的一个开源插件&#xff0c;支持对多种数据湖里的数据做分析计算。它的出现&#xff0c;使得 Postgres 能够像访问本地数据一样轻松访问 S3 等对象存储&#xff0c;轻松访问 Delta Lake 上的表格&#xff0c;具备数据湖分析能力。 pg_…

微信小程序实现容器图片流式布局功能,配合小程序原生框架使用。

小程序实现容器图片流式布局功能&#xff0c;因为目前论坛上也有很多博主出过类似的文章&#xff0c;这里我就以一个小白角度去讲一下如何实现的吧。给作者一点点鼓励&#xff0c;先点个赞赞吧&#x1f44d;&#xff0c;蟹蟹&#xff01;&#xff01; 目标 实现下方效果图 技术…

sonar3 使用 api/measures/componet 获取代码当,Java实现

最近团队在做一个技术架构相关的优化&#xff0c;当前的目标是想要通过代码量&#xff0c;系统架构入手。先统计到部门的代码量&#xff0c;如何进行代码行数的统计呢&#xff0c;因为我们采用的是Java技术栈&#xff0c;我就Java技术栈进行说明。 1、如何统计代码行数 要统计…

ZYNQ AXI4 FDMA内存读写

1 概述 如果用过ZYNQ的都知道,要直接操作PS的DDR 通常是DMA 或者VDMA,然而用过XILINX 的DMA IP 和 VDMA IP,总有一种遗憾,那就是不够灵活,还需要对寄存器配置,真是麻烦。对于我们搞 FPGA 的人来说,最喜欢直接了当,直接用FPGA代码搞定。现在XILINX 的总线接口是AXI4总线…

C-数据结构-树转存广义表-广义表转成树-实例

树转存广义表 save.c #include<stdio.h> #include<stdlib.h>#define FNAME "/tmp/out"struct node_st {char data;struct node_st *l,*r; };static struct node_st *tree NULL;//把tree提升到全局变量,当前文件int insert(struct node_st **root,int d…

latex中复制到word里面之后如何转变成word自带的公式

详细步骤如下&#xff1a; 第一步&#xff0c;将latex中的公式复制到word里面&#xff0c;例如&#xff1a;$r_1^d$ 第二步&#xff0c;选中$$里面的部分&#xff0c;也就是去掉$$&#xff0c;选中剩余的部分&#xff0c;例如&#xff1a;r_1^d 第三步&#xff0c;word工具栏里…

Web前端三大主流框架深度解析:React、Angular与Vue的较量

在现代Web开发中&#xff0c;前端框架已经成为开发人员的标准工具。它们不仅提供了丰富的功能&#xff0c;极大地简化了复杂的应用开发过程&#xff0c;还能提高开发效率和代码的可维护性。目前&#xff0c;React、Vue和Angular被认为是Web前端开发的三大主流框架。本文将深入探…

【Javascript修炼篇】你一天会犯几次低级错误

最近&#xff0c;尝试出一个javascript修炼篇&#xff0c;让编程技术更上一层楼。如果你对Javascript有兴趣&#xff0c;或者想要提供自己的编程技术&#xff0c;那么这个系列就很适合你。欢迎关注&#xff0c;持续更新中… 新手&#xff1a;作为人类&#xff0c;犯错实在太常…

echarts地图下钻+地图遮盖物散点

一、下载工具 npm i echarts echarts-gl axios -S -S是生产依赖默认是-S不写也可以 -D是开发依赖 二、引入工具 import * as echarts from "echarts"; import "echarts-gl"; import axios from "axios"; 三、HTML部分代码 <div class&…

【代码随想录】【算法训练营】【第21天】 [530]二叉搜索树的最小绝对差 [501]二叉搜索树的众数 [236]二叉树的最近公共祖先

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 21&#xff0c;天气不错的周二~ 题目详情 [530] 二叉搜索树的最小绝对差 题目描述 530 二叉搜索树的最小绝对差 解题思路 前提&#xff1a;二叉搜索树 思路&#xff1a;根据二叉搜索树的中…

长安链使用Golang编写智能合约教程(二)

本篇说的是长安链2.3.的版本的智能合约&#xff0c;虽然不知道两者有什么区别&#xff0c;但是编译器区分。 教程三会写一些&#xff0c;其他比较常用SDK方法的解释和使用方法 编写前的注意事项&#xff1a; 1、运行一条带有Doker_GoVM的链 2、建议直接用官方的在线IDE去写合…

公钥,私钥,数字签名,证书

公钥和私钥是一对&#xff0c;公钥是公开的&#xff0c;比如服务器持有公钥&#xff0c;对数据进行加密&#xff0c;接收端只有有对应的私钥才能对数据进行解密&#xff0c;私钥是不公开私自的。 数字签名跟上面是反过来的过程&#xff0c;客户端发送给服务器之前&#xff0c;…

奥枫软件Java要个16K遇到地狱级难度,醉了。。。

我只能说地狱难度&#xff0c;没绝对把握就别去了。我凭借前辈的经验&#xff0c;和当时天时地利人和&#xff0c;六道题答得很不错&#xff0c;但还是没通过。我有备而来都没过&#xff0c;现场写那些应该都是白忙活了。 一面 1&#xff0c;分割一个整数。如123&#xff0c;结…