精通Spring Framework (3) 深入掌握Spring AOP(一)

spring aop springaop 阅读详情

spring framework 两个特性:
1.依赖翻转
2.面向切面

DI 有助于应用对象之间的解耦,AOP可以实现横切关注点域他们所影响对象之间的解耦。

  • AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用 。*

aop可以理解为模块化编程,日志模块独立出来做成一个切面

一、Spring AOP

spring 提供了四种aop支持

  • 基于代理的经典AOP
  • 纯POJO 切面
  • @AspectJ 注解驱动切面
  • 注入式AspectJ 切面(适用于spring 个版本)

书中介绍 前三种 是Spring AOP实现变体, spring AOP构建在动态代理基础上。
所以 spring 对于aop 的支持仅限于拦截方法。

spring aop 基于动态代理实现,AOP的拦截功能是由java中的动态代理来实现的。在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常时候执行。不同的切入时机对应不同的Interceptor的种类,如BeforeAdviseInterceptor,AfterAdviseInterceptor以及ThrowsAdviseInterceptor等)。

动态 代理有两种实现,基于jdk反射的动态代理,被代理对象的子类,要求被代理类继承接口,
cglib 实现既可以是类也可以是接口, 针对字节码处理。

分析:在编写纯净的springframework 项目时,想使用spring AOP

需要额外引入:

org.aspectj:aspectjweaver:1.9.5
org.assertj:assertj-core:3.16.1

支持切入点表达式和 切面注解

如果 缺少引入则会报错

Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.aop.aspectj.AspectJAfterReturningAdvice] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@e73f9ac]
	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:481)
	at org.springframework.util.ReflectionUtils.doWithLocalMethods(ReflectionUtils.java:321)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:267)
	... 33 more
Caused by: java.lang.NoClassDefFoundError: org/aspectj/lang/JoinPoint
	at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
	at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3166)
	at java.base/java.lang.Class.getDeclaredMethods(Class.java:2309)
	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:463)
	... 35 more
Caused by: java.lang.ClassNotFoundException: org.aspectj.lang.JoinPoint
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
	... 39 more

找不到切点,分析日志发现找不到切点。
可以推测spring-aop 仅仅是对aop的动态代理支持。

@interface Aspect 注解和 xml 中 切面的配置需要引入上述两个包

1.1 通知 advice

公共的逻辑的抽象,模块化的执行代码,例如要记录登录用户的信息,登录方式多种,那么针对登录的Controller 或者Service 可以统一执行 一个advice的方法记录 用户IP 地址,用户登录时间,用户登录Client的信息。

通知定义了切面是什么何时使用。除了描述切面要完成的工作,通知还解决了何时执行这个工作的问题

spring的切面可以应用5中类型的通知

  • 前置通知 Before 目标方法被调用之前
  • 后置通知 After 目标方法完成之后,此时不关系输出的是什么
  • 返回通知 After-returning 目标方法成功执行之后
  • 异常通知 After-throwing 目标方方法抛出异常后调用
  • 环绕通知 Around 通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义行为

环绕通知

前四种通知容易理解和实践,重点分析一下环绕通知

环绕通知(@Around):包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型,环绕通知可以在方法调用前后完成自定义的行为,它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行

public class XmlAudienceAround {
    public Object aroundPringLog(ProceedingJoinPoint pjp) {
        Object rtValue = null;
        try {
            Object[] args = pjp.getArgs();//得到方法执行所需的参数

            if (args != null) {
                for (Object o : args) {
                    if (o instanceof String) {
                        System.out.println("String: "+o.toString());
                    }
                    if (o instanceof Computer) {
                        System.out.println("age: " + ((Computer) o).getAge());
                    }

                }
            }

            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。前置");

            rtValue = pjp.proceed(args);//明确调用业务层方法(切入点方法)

            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。后置");

            return rtValue;
        } catch (Throwable t) {
            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。异常");
            throw new RuntimeException(t);
        } finally {
            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。最终");
        }
    }

环绕通知内可以获取 切点的入参,根据入参写对应的逻辑处理,来决定是否执行切点还是执行 advice

可以修改入参

环绕通知可以影响切点代码的执行。

ProceedingJoinPoint is only supported for around advice

环绕通知可以获取连接点入参 出参

后置通知和返回通知的区别

返回通知可以获取到连接点方法返回参数

public void finish(JoinPoint joinPoint, Computer computer) {
        joinPoint.getArgs();
        System.out.println(computer.toString());
        System.out.println("4.finish");
    }
<aop:aspect id="aspects" ref="monitor">
            <aop:pointcut id="pointCutAfterReturning" expression=
                    "execution(* com.fancv.scan.Person.watch(..))"/>
            <aop:after-returning method="all" pointcut-ref="pointCutAfterReturning"/>
            <!--  <aop:around method="finish" pointcut-ref="pointCutAfterReturning"/>-->
            <aop:before method="take" pointcut-ref="pointCutAfterReturning"/>
            <aop:after-returning method="finish" pointcut-ref="pointCutAfterReturning" returning = "computer"/>
        </aop:aspect>

1.2 切点 pointcut

业务层代码中某个点,根据AOP不同的实现技术 这个点的形态不同,基于Spring AOP

动态代理的AOP 精确到类中方法

1.3 连接点 joinpoint

应用执行过程中插入的一个点,例如调用方法时,抛出异常时,修改字段时。

连接点是切面里的一段逻辑,处理 切点触发前后 环绕时的逻辑。

1.4 切面 Aspect

切面是通知和切点的结合

1.5 引入 Introduction

  <aop:declare-parents types-matching="com.fancv.aop.LiLei"
                                 implement-interface="com.fancv.aop.UserValidator" default-impl="com.fancv.aop.UserValidatorImpl"></aop:declare-parents>

给类Lilei 引入了UserValidatorImpl 的方法

具体原理猜测是动态代理

 Chinese lilei = (Chinese)context.getBean("lilei");
        lilei.Say();



        MyPerson person = (MyPerson) context.getBean("person");
        person.st();
        Computer c = new Computer("level", 12, true);
        UserValidator u=(UserValidator)context.getBean("lilei");
        u.validate(c);

1.6 织入 Weaving

一个过程,可以理解为 spring aop 动态代理的过程

编译期 AspectJ 采用的方式

类加载期 特殊的类加载器

运行期 spring aop 采用此方式

二、 AspectJ 编译实现AOP

下一篇继续

参考资料:

  1. 《spring 实战》(第四版)
  2. idea中配置 aspect编译
  3. spring aop 动态代理原理
  4. spriing aop 获取连接点入参出参
Spring AOP切入点数据的获取 遗留问题还存在一个问题,我们可以通过ProceedingJoinPoint执行切入点函数,那么我们在环绕通知中可以获取到数据吗? 阅读详情

相关推荐

Spring Framework 7.028.Spring AOP API(一)

摘要:本文介绍了Spring框架的AOP API核心组件,包括Advice通知接口、Pointcut切入点接口和Advisor组合器。详细讲解了前置、环绕等通知类型的实现方式,以及通过ProxyFactory创建动态代理的流程。文章还对比了JDK动态代理和CGLIB代理的区别,并展示了如何在Spring IoC容器中集成AOP配置。这些底层API虽然已被注解方式取代,但理解其原理对掌握Spring AOP机制很有帮助。

无 181

SpringAOP报错:ProceedingJoinPoint is only supported for around advice

文章目录前言一、如何解决?二、为什么?三、总结 前言 今天想使用AOP实现将一些自定义日志快捷方便的记录到数据库中时,启动项目时报错了。 错误内容如下所示: BeanPostProcessor before instantiation of bean failed; nested exception is java.lang.IllegalArgumentException: ProceedingJoinPoint is only supported for around advice 一、如何解决?

Coding&Sharing 1万+

某音播放量查询,播放量接口研究,最新版本抓包,修改SO文件绕过SSL

本教程适用于某音27.8,64位版本,32为版本及某音旁侧版本修改方法大同小异,部分旁侧版本修改之后模拟器可能无法抓包,真机测试均可正常抓包,此方法修改后绝大部分包可以正常抓取,但部分包无法抓取,例如验证码,内置浏览器功能,如需抓取此类包可通过 Postern + Charles 实现。

byalipus的博客 1万+

通知的知识点

通知的讲解 关于AOP通知的讲解 第一类: @Before(“pointcut()”) @AfterReturning(“pointcut()”) @AfterThrowing(“pointcut()”) @After(“pointcut()”) 可以记录程序执行的各个过程. 为日志提供记录. 第二类: @Around(“pointcut()”) 可以控制目标方法是否执行. 环绕通知可以控制业务流转的过程!!! 例子: 权限的校验 缓存系统 异常的处理等 ProceedingJoinPoint 只

qq_44772261的博客 1322

MATLAB2022b安装

图文并茂,手把手教会你怎么安装MATLAB2022b

1万+

MTK MT6833平台屏幕与TP驱动移植实战:从FAE伪代码到内核模块集成

本文详细介绍了在MTK MT6833平台上进行屏幕与TP驱动移植的完整实战流程。文章从解析供应商提供的初始化伪代码入手,逐步拆解了在LK阶段点亮屏幕、在内核层集成Panel驱动以支持休眠唤醒,以及移植并调试sitronix_ts触摸驱动的核心步骤与关键技巧,为嵌入式开发人员提供了从零到一集成新硬件的清晰指南。

rnn9storyteller的博客 441

Aop报错ProceedingJoinPoint is only supported for around advice

这是因为在返回后通知(@AfterReturning) 和抛出异常后通知(@AfterThrowing) 的方法中不能使用ProceedingJoinPoint, 使用JoinPoint即可解决

yjt520557的博客 2万+

芯片硅前验证技术与驱动工程师实战指南

硅前验证是芯片开发流程中的关键环节,通过pre-silicon simulation等技术手段在流片前验证设计正确性。其核心技术包括软件仿真、FPGA原型验证和硬件仿真器解决方案,涉及Linux驱动开发、芯片架构理解和波形分析等核心技能。作为连接芯片设计与系统集成的桥梁,硅前验证能早期发现设计缺陷,节省数百万美元流片成本。以Cadence Palladium为代表的硬件仿真器,通过专用服务器系统实现比纯软件方案快100-1000倍的仿真速度,为驱动工程师提供完整的外设模型验证环境。掌握硅前验证技术可显著提升

weixin_42522857的博客 323

springboot踩坑日记——使用AOP@Before注解报错:ProceedingJoinPoint is only supported for around advice

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2019-03-08 10:27:41.504 ERROR 18692 --- [ main] o.s.boot.SpringApplication ...

ityqing的博客 1万+

nacos3.1.0适配国产数据库

Nacos 3.1.0适配国产数据库指南 本文介绍了Nacos 3.1.0版本适配达梦数据库和人大金仓数据库的具体步骤。主要内容包括:添加达梦和人大金仓的JDBC驱动依赖,修改nacos-persistence模块的配置文件及相关Java类,以及打包和运行注意事项。文章特别指出3.1.0版本需要JDK17环境,并提供了解决常见问题的建议,如添加VM options配置和不同启动方式等。通过本文的配置指导,可以实现Nacos服务在国产数据库环境下的正常运行。

梦昼初的博客 1465

别再手动续期SSL证书了!用acme.sh配合阿里云DNS API,实现全自动HTTPS证书管理

本文详细介绍了如何使用acme.sh配合阿里云DNS API实现SSL/TLS证书的全自动管理,彻底解决手动续期带来的风险与不便。通过自动化部署流程,包括环境准备、API集成、多域名证书申请等关键步骤,帮助运维人员构建高效、可靠的HTTPS证书管理体系,显著提升安全性和运维效率。

weixin_29200485的博客 268

第 3 章:Spring Framework 中的 AOP

讲完了 IoC,我们再来聊聊 Spring Framework 中的另一个重要内容——面向切面编程,即 AOP。它是框架中众多功能的基础,例如声明式事务就是依靠 AOP 来实现的。此外,Spring 还为我们提供了简单的方式来使用 AOP,这有助于简化业务代码中一些共性功能的开发。本章我们会一起去了解 AOP 的基本概念,以及 AOP 在 Spring Framework 中的实现,并学习如何通过使用注解和 XML 文件的方式来配置 AOP 相关的功能。

Binge毕设 2137

Vivado IP核:AXI Uartlite的使用经验分享

1. IP基本设置 在Vivado中,打开IP Catalog,搜索“uart”: 双击“AXI Uartlite”,进入IP配置界面: 这里可以配置IP的具体参数,设置时钟频率、波特率等,完成后,生成IP即可。 2. IP的时序特点 点击下面的链接可以下载该IP核的官方指导文档: https://china.xilinx.com/support/documentation/ip_docume...

weixin_43265132的博客 1万+

[Spring Framework]AOP经典案例、AOP总结

概念AOP(AspectOrientedProgramming)面向切面编程,一种编程范式作用在不惊动原始设计的基础上为方法进行功能增强核心概念代理(Proxy)SpringAOP的核心本质是采用代理模式实现的连接点(JoinPoint)在SpringAOP中,理解为任意方法的执行切入点(Pointcut)匹配连接点的式子,也是具有共性功能的方法描述通知(Advice)若干个方法的共性功能,在切入点处执行,最终体现为一个方法切面(Aspect).........

十八岁讨厌编程的博客 834

Spark Sql 连接mysql

转载请务必注明原创地址为:http://dongkelun.com/2018/03/21/sparkMysql/ 1、基本概念和用法(摘自spark官方文档中文版) Spark SQL 还有一个能够使用 JDBC 从其他数据库读取数据的数据源。当使用 JDBC 访问其它数据库时,应该首选 JdbcRDD。这是因为结果是以数据框(DataFrame)返回的,且这样 Spark SQL操作轻松或便......

主要分享大数据相关的知识,如Spark、Hudi 1万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Spring framework(一)概述

一、Spring framework 即Spring,是其他Spring全家桶的基础和核心:包括SpringMVC、SpringBoot、SpringCloud、SpringData、SpringSecurity。 Spring由Rod Johnson创立,2004年发布了Spring框架的第一版,其目的是用户简化企业级开发的难度和周期。 1.1、核心 Spring是分层的JavaSE/EE一站式轻量级开源框架,以IoC(Inverse of Control,控制反转)和AOP(Aspect Oriente

全栈攻城狮JSON的博客 1万+

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Spring AOP framework

A key component of the Spring framework is the Aspect Oriented Programming (AOP) framework. Aspect oriented programming needs to decompose program logic into different parts called so-called concerns. Functions that span multiple points of an application a

随风而逝的博客 695

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Spring Framework:从入门到精通的全栈开发利器

Spring Framework是Java企业级开发的核心框架,采用IoC和AOP两大核心设计理念,通过控制反转实现松耦合,利用面向切面编程处理横切关注点。Spring生态系统包含Spring Boot(简化配置)、Spring Data(统一数据访问)和Spring Security(安全解决方案)等模块,支持Web应用、微服务、批处理等场景。其设计遵循POJO优先、非侵入性和模块化原则,提供缓存、懒加载等优化手段。学习路径建议从基础概念入手,逐步掌握各模块功能,最终实现企业级应用开发。Spring以其灵

2501_93502037的博客 781

Spring Framework(超详细)

Bean相关依赖相关。

2301_80744893的博客 2175

Spring Framework源码使用 spring-aspects AOP遇到的问题

在编译好的Spring Framework使用Aspects AOP 继续上一篇,编译Spring Framework5.1源码文章。现在要使用Aspects AOP也可能会遇到一些问题,现在这篇文章带你们解决这个问题。 1.导入AOP 我们先看看导入spring-aspects 这个包,然后在一个配置类打上@EnableAspectJAutoProxy这个注解会出现什么样的错误。 我们在配置一个AOP切面类,在类里面声明一个切入点,声明前置通知、后置通知、环绕通知。然后开始启动spring, 会出

linyou? 2890

Spring FrameWork AOP

以上就是静态代理的全流程,总体来说,就是通过代理角色在不改动源代码的情况下,实现需求,并可以添加操作。这里的运行机制是通过链接InvocationHandler接口,及Proxy类实现,在了解了静态和动态代理后,就可以实现AOP面向切面编程了。例子:在执行方法前后加入语句。下面给出一个代理案例:买房。例子:实现买房动态代理。

m0_65376383的博客 846

Spring Framework AOP详解

此前对于AOP的使用仅限于声明式事务,除此之外在实际开发中也没有遇到过与之相关的问题。最近项目中遇到了以下几点需求,仔细思考之后,觉得采用AOP来解决。一方面是为了以更加灵活的方式来解决问题,另一方面是借此机会深入学习SpringAOP相关的内容。本文是权当本人的自己AOP学习笔记,以下需求不用AOP肯定也能解决,至于是否牵强附会,仁者见仁智者见智。 对部分函数的调用进行日志记录,用于观察特

cqboy1991的专栏 1025

[Spring Framework]AOP初识

Spring有两个核心的概念,一个是IOC/DI,一个是就是AOP。AOP是在不改原有代码的前提下对其进行增强。面向切面编程,一种编程范式,指导开发者如何组织程序结构。面向对象编程我们都知道OOP是一种编程思想,那么AOP也是一种编程思想,编程思想主要的内容就是指导程序员该如何编写程序,所以它们两个是不同的编程范式。AOP的作用在不惊动原始设计的基础上为其进行功能增强,前面咱们有技术就可以实现这样的功能即代理模式。名称类型配置类注解位置配置类定义上方作用开启注解格式AOP功能。......

十八岁讨厌编程的博客 658

精通Spring Framework (4) 深入掌握Spring AOP(二)

二、 AspectJ 编译实现AOP AspectJ 是静态代理的增强,所谓的静态代理就是 AOP 框架会在编译阶段生成 AOP 代理类,因此也称为编译时增强。 AspectJ 是 Java 语言的一个 AOP 实现,其主要包括两个部分: 第一个部分定义了如何表达、定义 AOP 编程中的语法规范,通过这套语言规范,我们可以方便地用 AOP 来解决 Java 语言中存在的交叉关注点问题 另一个部分是工具部分,包括编译器、调试工具等。 AspectJ 是最早、功能比较强大的 AOP 实现之一,对整套 AOP 机

keep_learn的专栏 243

初探Spring AOP framework

这是我对Spring AOP framework的一点点探索 - 一个class和method调用的日志拦截处理,纪录方法的调用顺序。我希望这些可以帮助你理解spring aop 并且写出你自己的拦截器。 在spring 里面用拦截器需要扩展org.aopalliance.intercept.MethodInterceptor 接口的这个方法:

leagle 3007

你真的了解Spring Framework吗?

现在做Java Web开发,想必很少有人不知道Spring Framework。对于初学者来讲可能只接触过其中的一两个模块,对于Spring 平台没有一个整体上的认识,核心概念IoC&DI也是一知半解。本文就与读者来一探究竟,揭开Spring 神秘的面纱。Java 框架   上世纪90年代,使用Java开发Web应用普遍使用J2EE标准,J2EE具有平台无关性,对事务、消息等企业级的特性都有很好

Just do it! 1万+
上一篇: 十六进制文件编辑器MadEdit
下一篇: 精通Spring Framework (4) 深入掌握Spring AOP(二)
hamish-wu
博客等级 码龄15年 2814粉丝 162原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值