AOP介绍

AOP是一种面向切面编程的思想,用于解决横切关注点,如日志、事务管理。SpringAOP是其实现,包括切面、切点、通知等概念。通知类型包括前置、后置、返回、异常和环绕通知。SpringAOP使用动态代理实现,可以选择JDK或CGLIB方式。文章还介绍了切点表达式的解析和SpringAOP的织入原理。
摘要由CSDN通过智能技术生成

AOP的介绍

AOP:AOP是一种思想;面向切面编程。它对某一类的事情做集中处理;更准确的说是面向集中功能的编程
Spring AOP:AOP思想的一种实现

AOP作用:AOP 可以扩充多个对象的某个能⼒;像是对面向对象一种补充和完善。
登录功能判断
统⼀⽇志记录
统⼀⽅法执⾏时间统计
统⼀的返回格式设置
统⼀的异常处理
事务的开启和提交等

Spring AOP相关概念

相关概念:

切面(类):代表一个AOP类型(处理的事件是什么);一个项目可能有多个AOP;对应不同功能的实现。比如:用户登录功能判断、日志的统计记录

切点(方法):定义拦截规则

通知(方法具体实现):切面在特定切入点处要执行的代码。执行AOP逻辑业务

连接点:可能触发这个切点(方法)的点叫连接点。比如:我们要进行删除文章;里面就涉及一个判断用户登录状态;这个删除文章按钮就是连接点

细谈通知

切面的目标是它要完成的工作;这个工作就是通知(描述了在哪些连接点上应用哪些通知);在Spring切面类可以在方法加以下注解;设置其方法为通知方法;当满足条件后就进行方法的调用:
**前置通知:**使⽤ @Before:通知⽅法会在⽬标⽅法调⽤之前执⾏。

**后置通知:**使⽤ @After:通知⽅法会在⽬标⽅法返回或者抛出异常后调⽤;也可以访问目标方法的返回结果。

**返回通知:**使⽤ @AfterReturning:通知⽅法会在⽬标⽅法返回后调⽤。返回通知可以修改这个返回结果并最终返回给调用者,从而影响调用者最终得到的结果。

public Object afterReturningAdvice(Object returnValue) {
   //对返回结果进行修改   int modifiedReturnValue = (int) returnValue + 1;
   // 返回修改后的结果
   return modifiedReturnValue;
}

**异常通知:**使⽤ @AfterThrowing;通知⽅法会在⽬标⽅法抛出异常后调⽤。

**环绕通知:**使⽤@Around:通知包裹了被通知的⽅法,在被通知的⽅法通知之前和调⽤之后执⾏⾃定义的⾏为。比较特殊;需要传一个方法体(ProceedingJoinPoint joinPoint)对象;通过这个对象的proceed()方法去调用你的目标方法。(特别适合方法执行时间的统计)

Spring AOP使用

准备工作

1:正常创建Spring项目;添加Spring Web依赖;添加AOP依赖
在这里插入图片描述
这个应用商店也不是万能的;所以我们得去中央仓库寻找依赖
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

使用:在启动类同级或者子类下创建切面
在这里插入图片描述
AOP的实现有:Spring AOP;AspectJ;而spring aop出的比较晚;aspectj比较早诞生并被广泛使用;spring aop也变成兼容这个东西。语法是AspectJ的;具体实现是Spring AOP这个框架。Spring AOP也保留这个注解名字是AspectJ。

前置通知具体实现

1:创建切点(定义拦截规则)
在这里插入图片描述

拦截内容设置:
这里拦截是固定的写法;通过修改里面的内容实现不同的拦截(我是要拦飞机还是拦火车呢)
星号就是不管什么返回值都去拦截。后面就是要拦截的包名+类名;先只拦截这里的。后面的 . *是拦截的方法。当你写的是.a那就是拦截a开头的方法。参数如果没要求就是括号里面两个点(…)。。如果只要拦截int参数;那你就写int。

2:切点通知实现
在这里插入图片描述

3:连接点实现
上面的操作还没有连接点(所有可能触发切点的点);它是不会触发前置方法的执行
在这里插入图片描述
通过以下效果发现确实拦截到;并且执行了前置方法(我们在配置规则里写的就是拦截Usercontorller的所有方法;如果你是在其它类就不会生效;具体看你是怎么配置规则的)
在这里插入图片描述
后置通知、异常通知、返回通知写法都是一样的;只是注解不同

环绕通知

环绕通知特殊一点;把事件的本身交给你;ProceedingJionPoint代表我要访问的方法本体;所以环绕通知可以完全控制方法调用流程的通知;你可以在中间做其它事情。比如:决定是否执行被通知的方法,以及如何处理异常和返回值。

在这里插入图片描述
在这里插入图片描述
上述的代码;我们通过一个调试的手段也能看到这个对象里面的情况;它确实去在中间调用我们的目标方法

在这里插入图片描述
我们在执行上述环绕通知;执行流程会受到前置方法和后置方法影响;所以我们得把前置方法给注释掉再进行测试。如果前置方法和后置方法都存在。执行顺序如下
在这里插入图片描述

配置规则表达式解析

在这里插入图片描述
AspectJ支持三种通配符:
""通配符:可以匹配任意个字符;只能匹配一个元素(包、类、方法、方法参数)
"…"通配符:可以匹配多个元素,表示类时必须和 * 联合使用
"+"通配符:表示按照类型匹配指定类的所有类;必须跟在类名后面;比如:com.cba.Stu+表示继承该类的所有子类包括本身。
execution(<修饰符><返回类型><包.类.⽅法(参数)><异常>)
中间是拦截的种类;修饰符是可以省略的。类后面可以加+;表示拦截它和它子类;方法可以用
表示拦截所有方法;拦截所有参数可以用…
修饰符:一般省略;标识度不高;我们写修饰符通常都是public。* 表示任意标识符都可以
返回类型:不能省略;写void拦截返回没有值的;*代表任意
包:
在这里插入图片描述
类:

  • 任意 、*test 则是以test结尾、Test *则是以Test开头、UserTest 固定类

方法名:
不能省略 * 任意、addUser 固定方法、add * 以add开头、*add 以add结尾

参数:
() 指定无参、(int)指定int 、(int,int)指定两个int、(…)任意参数
throws:
可省略,一般不写

Spring AOP原理

Spring AOP基于动态代理模式实现,主要分为JDK动态代理实现和CGLIB字节码生成实现两种方式。
使用代理就能帮你招待客人;遇到非法就拦截在外。如果我直接在目标对象处理;那我的添加登录效验的代码还得加入到逻辑里面;我通过代理就可以把登录没效验的筛选掉
在这里插入图片描述
动态代理:动态代理(根据程序特征在运行生成代码)spring AOP会根据不同场景选择动态代理的实现功能;
静态代理:手动编码实现代理类并在程序运行前进行编译的代理方式,代理类和目标类都是在编译期确定;提起写好的。

织入:代理生成时机
1:编译期;切⾯在⽬标类编译时被织⼊。这种⽅式需要特殊的编译器。AspectJ以这种方式织入
2:类加载期;切⾯在⽬标类加载到JVM时被织⼊。这种⽅式需要特殊的类加载器,它可以在⽬标类被引⼊应⽤之前增强该⽬标类的字节码。
3:运行期;切⾯在应⽤运⾏的某⼀时刻被织⼊。⼀般情况下,在织⼊切⾯时,IOC容器会为⽬标对象动态创建⼀个代理对象。SpringAOP以这种⽅式织⼊切⾯的。

动态代理实现方式:
JDK动态代理:通过反射实现;速度快;被代理的类一定要实现接口
CGLIB动态代理:通过字节码增强技术(生成动态子类;子类去调用父类方法;你看不到的);动态生成代理对象。(通过代理类的子类来实现的动态代理;不能被final修饰)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

20计科-廖雨旺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值