(未完成)【Spring专题】SringAOP底层原理解析——阶段三(AOP)

目录

  • 前言
  • 前置知识
    • 代理范式
    • Spring动态代理的实现
  • 课程内容
    • 一、动态代理的实现
      • 1.1 Cglib动态代理
      • 1.2 JDK动态代理
      • 1.3 ProxyFactory:Spring对两种代理的封装
    • 二、AOP基础知识
      • 2.1 AOP基础概念回顾
      • 2.2 SpringAOP实现方式的发展历程
    • 三、底层源码解析
      • 3.1 概念回顾
      • 3.2 核心方法讲解
  • 学习总结

前言

前置知识

代理范式

什么是代理模式?代理模式的解释:为其他对象提供一种代理以控制对这个对象的访问,增强一个类中的某个方法,对程序进行扩展。
少年可曾听闻【代理范式】?它的伪代码一般如下:(Cglib动态代理采用的方案

class 被代理类 {function 方法A();
}class 代理类 <<继承>> 被代理类 {被代理类 targetObject;@Overridefunction 方法A() {// 这里写被加强的逻辑targetObject.方法A();// 也可以在这里写}
}

或者用java代码表示如下:

// 被代理对象
public class ProxyTarget {public void run() {System.out.println("这是普通对象的run");}
}// 代理对象
public class ProxyModel extends ProxyTarget {private ProxyTarget proxyTarget;public void setProxyTarget(ProxyTarget proxyTarget) {this.proxyTarget = proxyTarget;}@Overridepublic void run() {System.out.println("我代理对象可以在这里做加强---1");super.run();System.out.println("我代理对象也可以在这里做加强---2");}
}

但是,代理模式的实现其实还有一种,但前提是被代理的类存在接口。它的代理范式伪代码如下:(JDK动态代理采用的方案

class 被代理类 <<实现>> 接口A {function 实现自接口A的方法();
}class 代理类 <<实现>> 接口A {被代理类 targetObject;@Overridefunction 实现自接口A的方法() {// 这里写被加强的逻辑targetObject.方法A();// 也可以在这里写}
}

Spring动态代理的实现

我把它放到【课程内容】里面了,因为我怕大家不重视

课程内容

一、动态代理的实现

我相信有经验的朋友,应该都知道,我们Java里面通常使用的代理方式有两种,分别为:JDK动态代理,以及Cglib动态代理。下面就给大家简单演示一下,这两种动态代理的简单使用示例。
在言是两种代理之前,需要一个基础类。如下:

@Component
public class UserService {public void test() {System.out.println("这是UserService的一个普通方法");}
}

在开始代理之前,再次重申一下为什么需要代理?
代理模式的解释:为其他对象提供一种代理以控制对这个对象的访问,增强一个类中的某个方法,对程序进行扩展。
就是,当我们需要增强某个方法的,又不想修改原有代码的时候(遵守设计原则里面的:开闭原则),一般就会考虑使用代理。在Spring里面就使用了下面两种方案来实现这个代理模式。

1.1 Cglib动态代理

在上面的UserService,如果我们new一个UserService对象,然后执行test()方法,结果是显而易见的。如果我们现在想在不修改UserService类的源码前提下,给test()增加额外逻辑,那么就可以使用Cglib动态代理机制来创建UserService对象了,比如:

 public static void main(String[] args) throws IOException {UserService target = new UserService();target.test();System.out.println("下面开始是cglib之后的逻辑了");// cglib{// 使用cglib增强类Enhancer enhancer = new Enhancer();enhancer.setSuperclass(UserService.class);// 定义额外的增强逻辑,增强对象enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("before...");Object result = methodProxy.invoke(target, objects);System.out.println("after...");return result;}}});// 动态代理所创建出来的UserService对象UserService userService = (UserService) enhancer.create();// 执行这个userService的test方法时,就会额外会执行一些其他逻辑userService.test();}}

得到的都是UserService对象,但是执行test()方法时的效果却不一样了,这就是代理所带来的效果。
上面是通过cglib来实现的代理对象的创建,是基于父子类的,被代理类(UserService)是父类,代理类是子类,代理对象就是代理类的实例对象,代理类是由cglib创建的,对于程序员来说不用关心。

1.2 JDK动态代理

除开cglib技术,jdk本身也提供了一种创建代理对象的动态代理机制,但是它只能代理接口,也就是UserService得先有一个接口才能利用jdk动态代理机制来生成一个代理对象,比如:

public interface UserInterface {void test();
}public class UserService implements UserInterface{@Overridepublic void test() {System.out.println("这是UserService的一个普通方法");}
}

利用JDK动态代理来生成一个代理对象的示例如下:

 public static void main(String[] args) throws IOException {UserService target = new UserService();target.test();System.out.println("下面开始是cglib之后的逻辑了");// jdk代理{// UserInterface接口的代理对象Object proxy = Proxy.newProxyInstance(UserService.class.getClassLoader(), new Class[]{UserInterface.class}, new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("before...");Object result = method.invoke(target, args);System.out.println("after...");return result;}});UserInterface userService = (UserInterface) proxy;userService.test();}}

如果你把new Class[]{UserInterface.class},替换成new Class[]{UserService.class},代码会直接报错:(这也证明了JDK采用的是第二种代理范式)

java.lang.IllegalArgumentException: UserService is not an interface

由于这个限制,所以产生的代理对象的类型是UserInterface,而不是UserService,这是需要注意的。

1.3 ProxyFactory:Spring对两种代理的封装

上面我们介绍了两种动态代理技术,那么在Spring中对它们进行了封装,封装出来的类叫做ProxyFactory,表示是创建代理对象的一个工厂,使用起来会比上面的更加方便,比如:

    public static void main(String[] args) throws IOException {UserService target = new UserService();ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.setTarget(target);proxyFactory.addAdvice(new MethodInterceptor() {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println("before...");Object result = invocation.proceed();System.out.println("after...");return result;}});UserInterface userService = (UserInterface) proxyFactory.getProxy();userService.test();}

通过ProxyFactory,我们可以不再关心到底是用cglib还是jdk动态代理了,ProxyFactory会帮我们去判断,如果UserService实现了接口,那么ProxyFactory底层就会用jdk动态代理;如果没有实现接口,就会用cglib技术,上面的代码,就是由于UserService实现了UserInterface接口,所以最后产生的代理对象是UserInterface类型。

二、AOP基础知识

2.1 AOP基础概念回顾

2.2 SpringAOP实现方式的发展历程

三、底层源码解析

3.1 概念回顾

3.2 核心方法讲解

学习总结

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

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

相关文章

Hive字符串数组json类型取某字段再列转行

一、原始数据 acctcontent1232313[{"name":"张三","code":"上海浦东新区89492jfkdaj\r\n福建的卡"...},{"name":"狂徒","code":"select * from table where aa1\r\n and a12"...},{...}]...…

使用proxman对iOS真机进行抓包

1 打开手机的safari 输入地址 http://proxy.man/ssl 2 下载证书代开设置页面&#xff0c;安装证书 设置信任证书 打开手机设置 &#xff0c;点击通用 点击关于本机、 点击证书信任设置 打开信任设置开关 4 设置手机代理 查看需要设置的代理地址 打开界面 在手机中按…

音频4A算法导论

+我V hezkz17进数字音频系统研究开发交流答疑群(课题组) 一 音频4A算法是? 音频4A算法是指自动增益控制(Automatic Gain Control, AGC)、自动噪声抑制(Automatic Noise Suppression, ANS)和自动回声消除(Automatic Echo Cancellation, AEC),主动降噪ANC(Active Noi…

软考高级系统架构设计师系列论文第100篇:论软件的可维护性设计

软考高级系统架构设计师系列论文第100篇:论软件的可维护性设计 一、摘要二、正文三、总结一、摘要 2020年3月1日至12月20日,我参加了“数据安全访问平台”项目的开发,担任系统分析员的工作。该项目是某行业用户“数据中心二期”建设的主要内容,目标是:建立数据统一访问接口…

【Java 高阶】一文精通 Spring MVC - 转换器(五)

&#x1f449;博主介绍&#xff1a; 博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家&#xff0c;WEB架构师&#xff0c;阿里云专家博主&#xff0c;华为云云享专家&#xff0c;51CTO 专家博主 ⛪️ 个人社区&#x…

Ribbon:listOfServers

解释&#xff1a; 配置了address的地址,请求会走address&#xff0c;也就是http://127.0.0.1:8081&#xff0c;通常用户与别的后端服务进行联调设置为其本地服务的ip。 如果将address:注释掉。 会走后面的XXX.feign.default-server地址&#xff0c;这个地址通常可以配一个网关…

“深入解析JVM:理解Java虚拟机的工作原理和优化技巧“

标题&#xff1a;深入解析JVM&#xff1a;理解Java虚拟机的工作原理和优化技巧 摘要&#xff1a;本文将深入探讨Java虚拟机&#xff08;JVM&#xff09;的工作原理和优化技巧。我们将从JVM的基本结构开始&#xff0c;逐步介绍其工作原理&#xff0c;并提供一些实际示例代码&am…

解决v-if作用下popup弹框滑动效果消失的问题

问题描述 做需求的时候需要封装一个popup的组件&#xff0c;需求是页面进来的时候需要请求接口获取到popup的内容&#xff0c;然后进行展示弹框&#xff0c;但是这里就有一个问题&#xff0c;因为popup是一个组件&#xff0c;接口又是异步操作的&#xff0c;父组件进来的时候就…

【秋招基础】后端开发——笔面试常见题目

综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了秋招算法的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于网上知识点进行的&#xff0c;每个代码参考热门博客和GPT3.5&#xff0…

python自动化入门之Python编写脚本实现自动化爬虫详解

想知道如何使用Python轻松高效地获取网络上的信息&#xff1f; 本篇文章将探索Python自动化爬虫&#xff0c;并展示如何编写实用的脚本。 1. 什么是Python爬虫&#xff1f; 爬虫顾名思义&#xff0c;就是像蜘蛛一样在网络上爬行&#xff0c;抓取各种有用信息的一种程序。而Pyt…

深入理解回调函数qsort:从入门到模拟实现

&#x1f341;博客主页&#xff1a;江池俊的博客 &#x1f4ab;收录专栏&#xff1a;C语言进阶之路 &#x1f4a1;代码仓库&#xff1a;江池俊的代码仓库 &#x1f3aa;我的社区&#xff1a;GeekHub &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐ 文章目录 前…

在树莓派上搭建web站点并发布互联网上线【无需公网IP】

文章目录 概述使用 Raspberry Pi Imager 安装 Raspberry Pi OS设置 Apache Web 服务器测试 web 站点安装静态样例站点将web站点发布到公网安装 Cpolar内网穿透cpolar进行token认证生成cpolar随机域名网址生成cpolar二级子域名将参数保存到cpolar配置文件中测试修改后配置文件配…

C/C++:C/C++在大数据时代的应用,以及C/C++程序员未来的发展路线

目录 1.C/C在大数据时代的应用 1.1&#xff1a;C/C数据处理 1.2&#xff1a;C/C数据库 1.3&#xff1a;C/C图像处理和计算机视觉 1.3.1&#xff1a;导读 2.C/C程序员未来的发展路线 2.1&#xff1a;图导 1.C/C在大数据时代的应用 C/C在大数据时代中仍然是一种被广泛应用的编…

小程序运营方式有哪些?如何构建小程序运营框架?

​如今&#xff0c;每个企业基本都做过至少一个小程序&#xff0c;但由于小程序本身不具备流量、也很少有自然流量&#xff0c;因此并不是每个企业都懂如何运营小程序。想了解小程序运营方式方法有哪些&#xff1f; 在正式运营小程序前&#xff0c;了解小程序的功能与企业实际经…

Webpack高频面试题

Webpack高频面试题 1 谈谈你对webpack的看法 现在的前端网页功能丰富&#xff0c;特别是SPA&#xff08;single page web application 单页应用&#xff09;技术流行后&#xff0c;JavaScript的复杂度增加和需要一大堆依赖包&#xff0c;还需要解决Scss&#xff0c;Less……新…

AS中回退git历史版本并删除历史提交记录

当您想把某个版本后的代码删除&#xff0c;回滚到指定的版本。可以使用一下的方法。 一、打开AS中git历史提交窗口 二、选择需要回滚的版本选项&#xff0c;右键弹出菜单。选择Reset Current Branch to Here... 三、选择 Hard 选项 soft&#xff1a;将合并的更改应用到当前分支…

【ARM】Day8 中断

1. 思维导图 2. 实验要求&#xff1a; 实现KEY1/LEY2/KE3三个按键&#xff0c;中断触发打印一句话&#xff0c;并且灯的状态取反 key1 ----> LED3灯状态取反 key2 ----> LED2灯状态取反 key3 ----> LED1灯状态取反 key3.h #ifndef __KEY3_H__ #define __KEY3_H__#in…

RCU安全引用计数

原文网址&#xff1a;https://lwn.net/Articles/93617 原文作者&#xff1a;Corbet 原文时间&#xff1a;2004年7月14日 内核提供了一种用于实现引用计数的简单机制kref&#xff1b;该机制是今年3月份完成的。kref机制的核心思想是&#xff0c;提供支持原子操作的计数器&…

CGAL 网格(Mesh)数据骨架提取

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 骨架是一种非常有效的形状抽象,其被广泛的用于分割、形状匹配、曲面重建、虚拟导航等领域。正如名称所示,一条曲线骨架本质上是曲线线性化的图结构,并且它不是由曲面(2D)组成的3D几何体的中轴线。 如下图所示,形…

蓝牙耳机语音信号处理之ENC算法

+他V hezkz17进数字音频系统研究开发交流答疑群(课题组) 1 什么是单麦谱减法降噪? 单麦谱减法降噪是一种音频信号处理技术,用于在单声道录音中减少噪音的方法。它基于频域分析和减法混叠原理。首先,通过将音频信号转换为频域表示(如快速傅立叶变换),可以将音频信号分解…