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

news2024/11/16 12:07:08

目录

  • 代理
    • 什么是代理
    • 代理模式
  • 静态代理
  • 动态代理
    • 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{
    @Override
    public void rentHouse() {
        System.out.println("我是房东,我出租房子");
    }
}
  1. 代理(中介,帮房东)
public class HouseProxy implements HouseSubject{

    //将被代理对象是声明为成员变量
    private HouseSubject houseSubject;
    public HouseProxy(HouseSubject houseSubject) {
        this.houseSubject = houseSubject;
    }
    @Override
    public 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{
    @Override
    public void rentHouse() {
        System.out.println("我是房东,我出租房子");
    }
    @Override
    public void saleHouse() {
        System.out.println("我是房东,我出售房子");
    }
}

3.代理类修改


public class HouseProxy implements HouseSubject{

    //将被代理对象是声明为成员变量
    private HouseSubject houseSubject;
    public HouseProxy(HouseSubject houseSubject) {
        this.houseSubject = houseSubject;
    }
    @Override
    public void rentHouse() {
        // 开始代理
        System.out.println("我是中介,开始代理");

        //代理房东出租房子
        houseSubject.rentHouse();

        //代理结束
        System.out.println("代理结束");
    }
    @Override
    public 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.coloradmin.cn/o/1705800.html

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

相关文章

线段树例题

目录 1.Sequence 2.Peach Conference 3.Permutation Subsequence 1.Sequence 题目描述&#xff1a; Given an array a consisting of n integers, on which you are to perform m operations of two types. 1.Given two integers x,y, replace the number of index x with n…

httpsok-v1.12.0支持LB证书自动部署

&#x1f525;httpsok-v1.12.0支持LB证书自动部署 介绍 httpsok 是一个便捷的 HTTPS 证书自动续签工具&#xff0c;基于全新的设计理念&#xff0c;专为 Nginx 、OpenResty 服务器设计。已服务众多中小企业&#xff0c;稳定、安全、可靠。 一行命令&#xff0c;一分钟轻松搞…

console.log——NPM库

前期回顾 Vue3 TS 项目实战 - 后台管理系统 - 按钮权限_vue3ts后台管理-CSDN博客 目录 &#x1f6a9;不使用NPM插件的方式 第一步&#xff1a;创建log函数-源码 第二步&#xff1a;注册到window上 第三步&#xff1a;扩展Window接口 第四步&#xff1a;确保类型文件…

leetcode 530.二叉搜索树的最小绝对差 、501.二叉搜索树中的众数 、236. 二叉树的最近公共祖先

leetcode 530.二叉搜索树的最小绝对差 、501.二叉搜索树中的众数 、236. 二叉树的最近公共祖先 leetcode 530.二叉搜索树的最小绝对差 题目链接&#xff1a;https://leetcode.cn/problems/maximum-binary-tree/description/ 题目&#xff1a; 给你一个二叉搜索树的根节点 r…

【Qt】Qt定时器类QTimer

在进行窗口程序的处理过程中, 经常要周期性的执行某些操作, 或者制作一些动画效果&#xff0c;看似比较复杂的问题使用定时器就可以完美的解决这些问题&#xff0c; Qt中提供了两种定时器方式一种是使用Qt中的事件处理函数这个在后续章节会给大家做细致的讲解&#xff0c;本节主…

常用目标检测预训练模型大小及准确度比较

目标检测是计算机视觉领域中的一项重要任务&#xff0c;旨在检测和定位图像或者视频中的目标对象。当人类观看图像或视频时&#xff0c;我们可以在瞬间识别和定位感兴趣的对象。目标检测的目标是使用计算机复制这种智能。 近年来&#xff0c;目标检测网络的发展日益成熟&#…

设计模式基础——设计原则介绍

1.概述 ​ 对于面向对象软件系统的设计而言&#xff0c;如何同时提高一个软件系统的可维护性、可复用性、可拓展性是面向对象设计需要解决的核心问题之一。面向对象设计原则应运而生&#xff0c;这些原则你会在设计模式中找到它们的影子&#xff0c;也是设计模式的基础。往往判…

力扣刷题--1528. 重新排列字符串【简单】

题目描述 给你一个字符串 s 和一个 长度相同 的整数数组 indices 。 请你重新排列字符串 s &#xff0c;其中第 i 个字符需要移动到 indices[i] 指示的位置。 返回重新排列后的字符串。 示例 1&#xff1a; 输入&#xff1a;s “codeleet”, indices [4,5,6,7,0,2,1,3] 输…

OpenMV的VisionBoard视觉识别开发板学习记录

此篇博客仅用于对VisionBoard的开发板的学习研究记录&#xff0c;没有教学内容。 一、资料来源 开发板资料链接 开发板环境搭建手册 开发板视频教程 板子的资料网站 openmv官方的网站 目录 一、资料来源二、针对 VisionBoard的目标识别和定位总结1. 目标识别功能1.1 物体检测…

大模型时代:生活将如何被重塑?

大模型时代&#xff1a;生活将如何被重塑&#xff1f; &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 博客首页 怒放吧德德 To记录领地 &#x1f31d;分享…

数据挖掘与机器学习——回归分析

目录 回归分析定义&#xff1a; 案例&#xff1a; 线性回归 预备知识&#xff1a; 定义&#xff1a; 一元线性回归&#xff1a; 如何找出最佳的一元线性回归模型&#xff1a; 案例&#xff1a; python实现&#xff1a; 多元线性回归 案例&#xff1a; 线性回归的优缺…

Codeforces Round 948 (Div. 2) D. XORificator(哈希)

题目 n*m(n*m<3e5)的矩阵&#xff0c; 实际为t(t<1e4)组样例&#xff0c;但保证sum n*m不超过3e5 你可以选一行把所有01翻转&#xff0c;问最多可以让多少列只有一个1&#xff0c;然后把你翻转的行输出 思路来源 其实题还挺裸的&#xff0c;教了一下潘老师&#xff0…

8D和FMEA的关系是什么?——FMEA软件

免费试用FMEA软件-免费版-SunFMEA 在质量管理领域中&#xff0c;8D和FMEA是两个非常重要的工具。它们各自有着独特的作用&#xff0c;但同时又存在着紧密的联系。本文旨在深入探讨8D和FMEA之间的关系&#xff0c;以及它们如何协同工作以提高产品质量和客户满意度。 8D&#x…

【JavaEE精炼宝库】多线程(3)线程安全 | synchronized

目录 一、线程安全 1.1 经典线程不安全案例&#xff1a; 1.2 线程安全的概念&#xff1a; 1.3 线程不安全的原因&#xff1a; 1.3.1 案例刨析: 1.3.2 线程不安全的名词解释&#xff1a; 1.3.3 Java 内存模型 (JMM)&#xff1a; 1.3.4 解决线程不安全问题&#xff1a; 二…

紫光展锐前沿探索 | 满足未来6G多差异化应用场景的技术体系思考

在6G架构/系统设计中&#xff0c;紫光展锐提出了未来6G空口“一体多翼”的技术体系概念&#xff0c;即“Big-Lite Multi-RAT”。本文将详细对该技术体系展开介绍。 “一体多翼”技术体系通过 “体”&#xff08;Big RAT&#xff09;和“翼”&#xff08;Lite RAT&#xff09;的…

数据结构:树(2)【堆排序】【堆排序的时间复杂度】【topk】

一.堆排序 关于排序我们还是挺熟悉的&#xff0c;像是冒泡排序&#xff0c;快速排序等等。这里多介绍一种也挺牛的排序&#xff0c;叫做堆排序。在我的上一篇博客里我们了解到了关于堆的概念&#xff0c;堆又分为大堆和小堆。那么如果我们在进行堆排序的过程中&#xff0c;我们…

cs与msf权限传递,mimikatz抓取明文密码

目录 一、cs与msf权限传递 二、mimikatz抓取明文密码 一、cs与msf权限传递 cs传到msf&#xff1a; 创建foreign监听器-->msf监听模块设置端口-->cs执行新建会话选择创建的监听器 1.创建监听器&#xff1a; 2.msf监听设置端口&#xff1a; use exploit/multi/hander s…

计算机网络学习

文章目录 第一章信息时代的计算机网络因特网概述电路交换&#xff0c;分组交换&#xff0c;报文交换计算机网络的定义和分类计算机网络的性能指标常见的三种计算机网络体系计算机网络体系结构分层的必要性计算机网络体系结构分层思想举例计算机网络体系结构中的专用术语 第二章…

类别型特征

#机器学习 #深度学习 #基础知识 #特征工程 #数据编码 背景 在现实生活中,我们面对的数据类型有很多,其中有的数据天然为数值类型具备数值意义,那么可以很自然地和算法结合,但是大部分数据他没有天然的数值意义,那么将他们送入到算法前,就需要对数据进行编码处理,将其转换为数…

php -v在cmd中正常显示 在vscode中却报错

效果展示 原因 在vscode中 终端是 PowerShell PowerShell 默认情况下它不会继承系统的PATH环境变量 解决方案 使用CMD作为终端 打开VSCode设置&#xff08;File > Preferences > Settings 或 Ctrl,&#xff09;。搜索 terminal.integrated.shell.windows。更改其值…