Spring AOP原理

(一)Spring AOP原理

  Spring AOP是基于动态代理来实现AOP的,但是在讲之前我们要来先认识一下代理模式

  1.代理模式

 其实代理模式很好理解,简单来说就是,原本有一个对象,然后来了另一个对象(我们称为代理),我们想访问对象时,不再直接对目标方法进行调用,是通过代理类间接调用

  为什么要使用代理模式?因为可能有些情况下,一个对象不适合或者不能直接引用另一个对象,代理模式就可以起到很好的中介作用

 既然我们不是直接访问对象,是通过代理类访问,那我们就可以在代理类中对我们想要访问的对象来进行功能的增强

 代理模式中的主要角色

subject:也就是业务接口类,可以是抽象类也可以是接口(不一定有,但我们怎么实现)

RealSubject:业务实现类,具体业务的执行,也就是被代理的对象

Proxy:代理类,RealSubject的代理

 代理模式分为静态代理和动态代理

静态代理:由程序员创建代理类并且实现,在程序运行前代理类的class文件就存在

静态代理:在程序运行时,再通过反射机制动态创建

1)静态代理

   我们可以简单把代理模式用房屋出租的例子来写出来

 首先我们要先写一个房东类,然后给代理开放一个接口,然后定义个代理类,帮房东出租房子

@Slf4j
public class HouseProxy implements  HouseSubject{HouseSubject subject;public HouseProxy(HouseSubject subject) {this.subject = subject;}@Overridepublic void rentHouse() {log.info("代理---开始代理");subject.rentHouse();log.info("代理---结束代理");}
}
public interface HouseSubject {public void rentHouse();
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;@RestController
@Slf4j
public class RealHouseSubject implements HouseSubject {@Overridepublic void rentHouse() {log.info("房东---开始出租");}
}

 我们可以看到,这个静态代理虽然完成了目标对象的代理,但是代码都写死了,如果我们要新添加别的方法,就需要全部再添加一遍,很不灵活

 这时就需要我们的动态代理了

2)动态代理

  相比于静态代理,动态代理时更灵活的我们不需要针对每个⽬标对象都单独创建⼀个代理对象,⽽是把这个创建代理对象的⼯作推迟到程序运⾏时由JVM来实现.也就是说动态代理在程序运⾏时,根据需要动态创建⽣成.

  java对动态代理进行了实现,常见的实现方式有两种:JDK动态代理 CGLIB动态代理

  JDK动态代理

1.我们还是要先定义一个接口及其实现类(也就相当于静态代理的房东类和他提供的接口)

2.自定义一个InvocationHandler接口并且重写invoke方法,在invoke方法中调用目标方法,并且自定义一些逻辑处理

3.通过Proxy.newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)方法创建代理对象

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class JDKInvocationHandler implements InvocationHandler {private Object object;public JDKInvocationHandler(Object object) {this.object = object;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("中介开始代理");final Object invoke = method.invoke(object, args);System.out.println("中介结束代理");return invoke;}
}

我们使用的时候也很简单

import java.lang.reflect.Proxy;public class Main {public static void main(String[] args) {HouseSubject houseSubject=new RealHouseSubject();HouseSubject proxy= (HouseSubject) Proxy.newProxyInstance(houseSubject.getClass().getClassLoader(), new Class[]{HouseSubject.class},new JDKInvocationHandler(houseSubject));proxy.rentHouse();}
}

只需要满足我们需要传递的参数即可    

那我们现在来简单讲解一下这个代码中比较陌生的地方

  1.invovationHandler

  这个接口是java动态代理的关键接口,他定义了一个单一方法invoke(),用来处理被代理对象的方法调用

 

 2.Proxy

 Proxy类中使用频率最高的方法就是newProxyInstance()这个方法就是来生成一个代理对象的

  首先第一个参数需要我们传递的时classLoader,然后第二个参数需要我们传递一个接口,第三个需要我们传递一个要代理的对象

  这里因为第二个参数是要提供一个接口的,但是我们又可以不提供这个接口,这就导致JDK动态代理有时候是无法实现的,这时就需要我们使用CGLIB动态代理

CGLIB动态代理

1.定义个被代理类(这里就可以不提供接口了)

2.自定义MethodIntercepter 并且重写intercept方法,类似于invoke

4.通过enhancer类的create()来创建代理类

 但是用之前我们需要先添加依赖

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

  代码的结构和JDK动态代理是很像的,所以这里就不写了,但是我们还是来讲一下两者代码间的差别

首先就是我们实现的接口不同了,这个接口定义的方法是intercept()用来增强目标

我们这里多路一个参数,但是MethodProxy与Method是类似的,都是调用被代理的方法

再来看看create方法

type就是被代理的类型,callback就是实现后的代理对象

(二)代理原码中的一个重要参数

  源码里有个重要的属性叫proxyTargetClass 默认是false,但是可以通过程序设置,那么这个值的true,false又代表了什么呢?

  我们再来强调一下,JDK动态代理只能代理接口,不可以直接代理类,CGLIB可以代理接口,也可以代理类

 Spring中默认proxyTargetClass的值是false,也就是优先使用JDK代理,只有代理类的时候才使用CGLIB代理    但是SpringBoot2.x之后默认值就是true了,默认是使用CGLIB代理

 我们可以在配置文件中更改这个默认值

面试题:

1)什么是AOP?

  AOP是面向切面编程,是一种思想-------对一类特定问题的统一处理就。比如Spring实现了AOP这种思想

2)Spring AOP的实现方式有哪些?

 我们可以使用@Aspect注解,自定义注解,xml的方式(但是现在不常用了),还可以基于代理的方式实现

3)Spring AOP的实现原理?

Spring AOP是通过动态代理实现的,分别是JDK动态代理,CGLIB动态代理

4)Spring使用了那种方式?

  在Spring我们两种方式都是用了,在源码中有一个proxyTargetClass这个参数,他的默认值是false,默认使用JDK代理,当我们提供了接口时我们就是用JDK代理,如果我们没有提供接口我们就是用CGLIB代理

  在我们的Spring Boot中,这个参数的默认值时true,就是默认使用CGLIB动态代理

5)JDK和CGLIB的区别?

 首先就是JDK动态代理是我们spring原生就提供了的,CGLIB则是需要我们外部引入依赖,并且两者的使用实现的接口,调用的方法都是不同,但是使用上的不同不是最重要的,JDK动态代理无法对没有提供接口的类进行代理,而CGLIB动态代理是可以的,也就是说CGLIB可以直接代理类,JDK不可以

 

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

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

相关文章

26.Redis主从架构

Redis主从架构 redis主从架构搭建&#xff0c;配置从节点步骤&#xff1a; 1、复制一份redis.conf文件 2、将相关配置修改为如下值&#xff1a; port 6380 pidfile /var/run/redis_6380.pid # 把pid进程号写入pidfile配置的文件 logfile "6380.log" dir /usr/local/…

3D-IC——超越平面 SoC 芯片的前沿技术

“3D-IC”&#xff0c;顾名思义是“立体搭建的集成电路”&#xff0c;相比于传统平面SoC&#xff0c;3D-IC引入垂直堆叠芯片裸片&#xff08;die&#xff09;和使用硅通孔&#xff08;TSV&#xff09;等先进封装技术&#xff0c;再提高性能、降低功耗和增加集成度方面展现了巨大…

同世界,共北斗|遨游通讯亮相第三届北斗规模应用国际峰会!

10月24日&#xff0c;第三届北斗规模应用国际峰会在湖南省株洲市隆重开幕&#xff0c;此次峰会以“同世界&#xff0c;共北斗”为主题&#xff0c;旨在加速北斗系统的市场化进程、促进其产业化布局及国际化拓展。全国政协副主席、农工党中央常务副主席杨震讲话并宣布开幕&#…

window7虚拟机VMware与主机共享文件

文件管理器》计算机网络右键》属性》高级共享设置——全部启用 新建文件夹》右键》属性》共享》选择可以共享的用户——我这里选的是所有用户 点击高级共享》权限》保存设置——设置文件权限 文件管理器》计算机网络》右键》属性》————查看虚拟机计算机名称 主机访问 主机…

构建安全基石:网络安全等级保护定级指南

在数字化时代&#xff0c;网络安全已成为企业与个人不可忽视的重要课题。网络安全等级保护定级指南&#xff0c;作为国家指导网络安全保护的重要文件&#xff0c;为各类机构提供了精准的安全防护蓝图。本文旨在深度解析网络安全等级保护定级指南的精髓&#xff0c;助力建构全面…

HarmonyOS 5.0应用开发——Navigation实现页面路由

【高心星出品】 文章目录 Navigation实现页面路由完整的Navigation入口页面子页面 页面跳转路由拦截其他的 Navigation实现页面路由 Navigation&#xff1a;路由导航的根视图容器&#xff0c;一般作为页面&#xff08;Entry&#xff09;的根容器去使用&#xff0c;包括单页面&…

基于FPGA的以太网设计(五)

之前简单介绍并实现了ARP协议&#xff0c;今天简单介绍一下IP协议和ICMP协议。 1.IP协议 IP协议即Internet Protocol&#xff0c;是网络层的协议。 IP协议是TCP/IP协议族的核心协议&#xff0c;其主要包含两个方面&#xff1a; IP头部信息。IP头部信息出现在每个IP数据报中…

将 el-date-picker获取的时间数据转换成时间戳

在Vue.js中使用Element UI的el-date-picker组件时&#xff0c;你可以获取用户选择的日期并将其转换为时间戳。el-date-picker通常返回的是一个Date对象或一个格式化后的字符串&#xff08;取决于你如何配置它&#xff09;。下面是一个示例&#xff0c;展示了如何将el-date-pick…

Spring Cloud OAuth认证中心

在微服务架构中&#xff0c;由于不同的业务会拆分成不同的微服务&#xff0c;传统的单体项目一般是通过过滤器进行拦截校验&#xff0c;而微服务显然不可能分发到各个服务进行用户认证&#xff0c;这就需要由一个统一的地方来管理所有服务的认证信息&#xff0c;实现只登录一次…

松脂醇-落叶松脂素还原酶(pinoresinol-lariciresinol reductase, PLR)克隆与鉴定-文献精读71

菘蓝中松脂醇-落叶松脂素还原酶编码基因IiPLR2的克隆与功能分析 摘要 松脂醇-落叶松脂素还原酶(pinoresinol-lariciresinol reductase, PLR)是植物中木脂素生物合成的关键酶&#xff0c;能连续催化两步反应分别生成落叶松脂素和开环异落叶松脂素。落叶松脂素等木脂素类成分是…

Unity SpriteEditor 中的图集处理功能

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正 因为unity不只能做3d&#xff0c;还有2d游戏需要大量编辑处理图片素材&#xff0c;所以需要了解Sprite&#xff08;精灵&…

KPaaS 集成平台低代码在跨境电商行业的应用

在全球化的经济浪潮中&#xff0c;跨境电商行业蓬勃发展&#xff0c;机遇与挑战并存。随着业务规模的不断扩大和市场竞争的日益激烈&#xff0c;跨境电商企业面临着诸多复杂的业务管理和技术难题。KPaaS 业务集成扩展平台以其低代码的创新特性&#xff0c;为跨境电商行业带来了…

头歌——人工智能(机器学习 --- 决策树2)

文章目录 第5关&#xff1a;基尼系数代码 第6关&#xff1a;预剪枝与后剪枝代码 第7关&#xff1a;鸢尾花识别代码 第5关&#xff1a;基尼系数 基尼系数 在ID3算法中我们使用了信息增益来选择特征&#xff0c;信息增益大的优先选择。在C4.5算法中&#xff0c;采用了信息增益率…

银河麒麟相关

最近安装了银河麒麟server版本&#xff0c;整理下遇到的一些小问题 1、vmware安装Kylin-Server-V10-SP3-General-Release-2303-X86_64虚拟机完成后&#xff0c;桌面窗口很小&#xff0c;安装vmwaretools后解决&#xff0c;下载地址http://softwareupdate.vmware.com/cds/vmw-de…

leetcode-71-简化路径

题解&#xff1a; 1、以"/"作为分隔符对字符串进行分割得到数组names; 2、初始化一个栈stack&#xff08;python中的栈使用列表实现&#xff09;&#xff1b; 3、遍历数组names&#xff1b;如果当前元素为".."且栈不为空&#xff0c;则将弹出栈顶元素&a…

网络安全行业10大副业汇总,总有一个适合你

网络安全行业这10大副业汇总 总有一个适合你 引言 在当今的网络安全行业中&#xff0c;除了全职工作外&#xff0c;许多师傅还通过副业来增加收入、不断拓展自身技能&#xff0c;并积累更多实际操作经验&#xff0c;为职业发展增添了无限可能。 本文提供了10种适合各种类型…

Android13关于获取外部存储文件的相关问题及解决方案记录

Android的学习路上... 测试设备&#xff1a;vivo X90s安卓版本&#xff1a; Android13开发环境&#xff1a;AndroidStudio FlamingoSDK&#xff1a;33 最近我在Android13的环境下尝试写一个文件选择器&#xff0c;以便日后的开发使用。但是我们知道&#xff0c;从Android13 (A…

django restful API

文章目录 项目地址一、django环境安装以及初识restful1.1 安装python 3.10的虚拟环境1.2 创建django工程文件1.3 创建一个book app1.4 序列化(Django JsonResponse)1.4.1创建一个Models1.4.2 创建django的超级用户admin1.4.3 添加serializers.py生成序列化器1.5 FBV创建视图1…

用docker Desktop 下载使用thingsboard/tb-gateway

1、因为正常的docker pull thingsboard/tb-gateway 国内不行了&#xff0c;所以需要其它工具来下载 2、在win下用powershell管理员下运行 docker search thingsboard/tb-gateway 可以访问到了 docker pull thingsboard/tb-gateway就可以下载了 3、docker Desktop就可以看到…

ComfyUI初体验

ComfyUI 我就不过多介绍了&#xff0c;安装和基础使用可以看下面大佬的视频&#xff0c;感觉自己靠图文描述的效果不一定好&#xff0c;大家看视频比较方便。 ComfyUI全球爆红&#xff0c;AI绘画进入“工作流时代”&#xff1f;做最好懂的Comfy UI入门教程&#xff1a;Stable D…