精通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万+

Vivado时序违约小结

目录1. setup time违约1.1 逻辑级数太高1.2 Fanout太大2. hold time 违约2.1 异步信号处理导致hold time违约 1. setup time违约 建立时间是工程设计中最常遇到的问题了。一般说来,导致建立时间违例主要有两个原因:逻辑级数太大或者扇出太大,当然也可以尝试通过降频来解决建立时间违约。 1.1 逻辑级数太高 Levels指的是逻辑级数logic level,一个logic level的延迟对应的是一个LUT和一个Net的延迟,对于不同的器件,不同频率的设计能

mu_guang_的博客 7155

通知的知识点

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

qq_44772261的博客 1322

DISM错误87详解:RestoreHealth选项无法识别的修复方法

DISM(部署映像服务和管理工具)是Windows系统维护与修复的核心命令行工具,常与SFC(系统文件检查器)配合使用,用于扫描和修复组件存储损坏、系统文件缺失等问题。在执行系统健康检查时,用户常会遭遇错误87,提示“未在此上下文中识别出restorehealth选项”。该错误的本质并非工具损坏,而是命令参数结构不符合DISM的语法解析规则,或当前系统环境(如Windows 7、WinRE/PE、32位环境)不支持该参数。理解DISM的命令层级、参数挂载关系以及运行上下文,是精准排除故障的前提。通过核对标准

weixin_34116482的博客 477

基于SOEM的伺服电机控制实战:从配置到调试

本文详细介绍了基于SOEM的伺服电机控制实战,从硬件配置到软件调试的全过程。通过分享PDO映射、状态机控制、性能优化等核心技巧,帮助开发者快速掌握EtherCAT通信与伺服电机控制的关键技术,提升工控系统开发效率。

weixin_29165465的博客 520

Aop报错ProceedingJoinPoint is only supported for around advice

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

yjt520557的博客 2万+

使用xlwings在Python中对Excel表格进行操作是非常方便的,可以实现自动化处理、批量数据处理等功能

使用xlwings在Python中对Excel表格进行操作是非常方便的,可以实现自动化处理、批量数据处理等功能。本篇文章主要介绍如何使用xlwings对Excel表格进行多行多列数据设置和操作,并给出相应的源代码。接着,我们可以对这个范围内的所有单元格进行操作,如设置字体颜色、填充颜色、对齐方式等。以上就是使用xlwings对Excel表格进行多行多列数据操作和设置字体颜色、填充色和对齐方式的全部内容。最后,我们可以将数据写入到单元格中,也可以从单元格中读取数据。在Excel中,可以通过。

BUG?不存在的! 712

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万+

开心消消乐

1)当点击一个1时,该1变被反转为0,同时相邻的上、下、左、右,以及左上、左下、右上、右下8个方向的1(如果存在1)均会自动反转为0;2)进一步地,一个位置上的1被反转为0时,与其相邻的8个方向的1(如果存在1)均会自动反转为0;上述样例中,四个角上的1均在中间的1的相邻8个方向上,因此只需要点击一次即可。给定一个N行M列的二维矩阵,矩阵中每个位置的数字取值为0或1。在上述4 * 4的矩阵中,只需要点击2次,即可将所有的1进行消除。接下来N行表示矩阵的初始值,每行均为M个数,取值范围[0,1]

面试高手的博客 2729

Windows 镜像包大全(附百度云下载链接)

插入U盘,找到下载好的两个驱动软件,并安装,先打开驱动人生万能网卡版,安装好网卡驱动,可以接入wifi或者网线了,然后打开驱动精灵,按照提示,安装所有的驱动(中间要是让你重启,就先选择稍后再说,如果有的驱动安装好之后非要你重启,关不掉的那种,那你就重启吧),等全部安装好了,重启电脑。如果你有显卡,这里以英伟达举例,我是GTX960的,当你的驱动都安装好后,右键桌面,会出现一个英伟达控制面板。安装软碟通,下载之后,一直下一步就ok,啥也不用配置,到了最后一项点击“继续试用”即可。(下载里面的网卡版即可),

悦分享 7354

第 3 章:Spring Framework 中的 AOP

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

Binge毕设 2137

【单片机】STM32F103C8T6 最小系统板原理图

STM32F103C8T6是一款基于ARM Cortex-M3内核的32位微控制器,由STMicroelectronics(ST)公司生产。它是STMicroelectronics的STM32系列微控制器中的一员,被广泛应用于嵌入式系统和电子设备中。LQFP48封装(Low-profile Quad Flat Package,48引脚)SRAM(静态随机访问存储器):20 KB。支持JTAG调试和编程接口(可选)多个通用输入/输出口(GPIO)USB接口(用于USB设备模式)内置调试和编程接口(SWD)

q742971636的博客 6万+

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

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

十八岁讨厌编程的博客 834

【原理图PCB专题】案例:双排0.5mm间距座子转单排0.5mm间距座子Layout方案分析

本文提供一种分析思路,并通过实际案例来进行Layout方案分析的讲解。

一点硬件 456

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

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万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

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

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

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

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

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、付费专栏及课程。

余额充值