首页 > 其他分享 >AOP简单理解

AOP简单理解

时间:2024-02-16 15:33:25浏览次数:30  
标签:JDK 对象 AOP 代理 目标 理解 简单 动态 方法

代理框架图


代理模式通俗理解:目标对象A找工作需要租房,需要查询房子位置、价格和大小并交租,很麻烦,但如果通过房屋中介代理对象B,让B查询房子位置、价格和大小,A只需要交租即可

Spring AOP 解决的是 非业务代码抽取的问题,底层是动态代理技术,有JDK动态代理和CGLIB动态代理:

  • JDK动态代理只提供接口的代理
    • JDK运行时为目标类生成一个动态代理类$proxy*.class,动态代理类继承Proxy类并实现了目标类的接口,重写接口的所有方法以进行增强
    • 调用时,动态代理类先调用方法拦截处理器InvocationHandler#invoke()进行增强,再通过反射方式Method#invoke()调用目标方法
  • CGLIB动态代理
    • 通过ASM在运行时动态生成目标类的子类,即动态代理类继承目标类,重写目标类的所有方法以进行增强
    • 调用时,先通过动态代理类调用MethodInterceptor#intercept()进行增强,之后动态代理类调用目标类(父类)的方法
    • 目标类和其方法不能被final修饰
  • JDK方式生成动态代理类速度快于CGLIB,调用速度慢于CGLIB,老版本的CGLIB调用速度快于JDK,但由于JDK的版本升级,JDK7以上的动态代理性能已经高于CGLIB方式
public interface InvocationHandler {
    // proxy: 代理对象;method:目标对象方法的反射,目标对象方法的参数
    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable;
}
// loader:类加载器;interfaces:目标类的接口,h:方法拦截处理器
private static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) {
    
}

动态代理的代理对象 代理的是接口,且需要提供目标对象

JDK动态代理需要 有实现接口的类

CGLib动态代理

切入点表达式 指定拦截目标对象的方法,执行目标对象方法时,动态植入切面类方法

动态代理也有个约束:目标对象一定是要有接口的

cglib代理也叫子类代理,从内存中构建出一个子类来扩展目标对象的功能,在运行期扩展Java类与实现Java接口,拦截对象的方法

代理的类不能为final,final修饰的类不能继承

目标对象的方法不能为final/static

即使抽取成类还是会出现重复的代码,因为这些逻辑(开始、结束、提交事务)依附在我们业务类的方法逻辑中

AOP的理念:就是将分散在各个业务逻辑代码中相同的代码通过横向切割的方式抽取到一个独立的模块中

代理能干嘛?代理可以帮我们增强对象的行为!使用动态代理实质上就是调用时拦截对象方法,对方法进行改造、增强!

Spring对AOP的支持局限于方法拦截

  • 如果是单例的我们最好使用CGLib代理,如果是多例的我们最好使用JDK代理

原因:

  • JDK在创建代理对象时的性能要高于CGLib代理,而生成代理对象的运行性能却比CGLib的低。
  • 如果是单例的代理,推荐使用CGLib

标签:JDK,对象,AOP,代理,目标,理解,简单,动态,方法
From: https://www.cnblogs.com/jishaling/p/18017204

相关文章

  • 免费工具 Winsw 和 NSSM 适合对服务管理功能有一定要求的用户,且不想花费额外费用;SRVAN
    免费工具:SRVANY:优点:允许将任何可执行文件转换为服务。Windows自带工具,无需额外安装。简单易用,适合基本的服务管理需求。缺点:功能相对简单,不支持高级的服务管理功能。不再得到官方支持和更新,可能存在一些稳定性问题。Winsw:优点:简单易用,提供了一个简单的配置......
  • dremio SystemStoragePluginInitializer 简单说明.
    以前在关于ManagedStoragePlugin部分,简单说明了下SystemStoragePluginInitializer,今天再明确说明下SystemStoragePluginInitializer的特点继承自Initializer接口,可以实现一些轻量级服务的启动SystemStoragePluginInitializer的启动是通过InitializerRegistry类实现的,Initia......
  • CAP理论与BASE理论的关系及理解
    在探讨分布式系统时,我们经常会提到CAP理论。CAP理论是分布式计算中的一个基本原则,它指出在一个分布式数据存储系统中,Consistency(一致性)、Availability(可用性)和PartitionTolerance(分区容错性)这三个特性无法同时被满足。一、一致性(Consistency)一致性是指“所有节点在同一时间看到......
  • 快速部署最简单的 Git 服务 Gogs
    前面介绍了Gitlab的搭建,功能很强大,无论是cpu还是内存,要求机器的配置要高一些。如果没有比较高的机器配置,只使用最常用的Git代码托管功能,那么就使用Gogs来快速部署吧。Gogs是一款极易搭建的自助Git服务。旨在打造一个以最简便的方式搭建简单、稳定和可扩展的自助Git......
  • javascript import export 简单示例
    概述import是ES6引入的新特性,它允许你以声明式的方式导入其他模块中的内容。require是Node.js中的特性,它允许你使用一个函数来加载和导入其他模块。使用方法utils.jsexportconstadd=(a,b)=>a+b;exportconstsubtract=(a,b)=>a-b; index.jsimport*asutilsfrom......
  • Jsoup的快速使用--简单实用
    Jsoup的使用通常分为四步:1.导入jar包2.加载XML文档进内存,获取DOM树对象Document2.1获取类加载器ClassLoaderclassLoader=Demo1.class.getClassLoader();2.2使用类加载器找到XML文档的路径Stringpath=classLoader.getResourc......
  • Python之禅 (Although practicality beats purity.)的理解
    TheZenofPython,byTimPeters摘其中一句谈谈我的理解Althoughpracticalitybeatspurity.实用性有时比理论上的完美更重要。python看起来是不太完美,比如,很长时间都没有编译时的类型检查,开始时候认为这个是语言设计者的一个bug,但后来发现,过早的把精力放到类型上去,对于程......
  • 简单字符(串)输出:转义符应用
     即?*&\!_//\a@\\\r\n!//\\"_"/\\^!~zZ#include<stdio.h>intmain(){chara,b,c,d,e,f,g,h,i,j,o;a='?';b='*';c='&';d='\\';e='!';f=......
  • Go语言精进之路读书笔记第23条——理解方法的本质以选择正确的receiver类型
    和函数相比,Go语言中的方法在声明形式上仅仅多了一个参数,Go称之为receiver参数。receiver参数是方法与类型之间的纽带。Go方法特点:方法名的首字母是否大写决定了该方法是不是导出方法。方法定义要与类型定义放在同一个包内。由此可以推出,不能为原生类型(如int/float64/map等)添加......
  • 如何提升技术?-(GPT的标准回答,其实很多道理都是藏匿于看似简单、朴素的道理之中,只不过是
    快速提升技术需要多方面的努力和实践。以下是一些建议:明确目标:首先,你需要明确你想要提升的技术领域和目标。这样你才能有针对性地进行学习和实践。制定学习计划:制定一个详细的学习计划,包括要学习的知识点、实践项目、学习时间表等。这有助于你系统地掌握技术知识。深入学习:深入......