Spring AOP统一功能处理
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
⭐️前言⭐️
这篇文章主要介绍AOPAspect Oriented Programming——面向切面编程的思想它是对某一类事情的集中处理也是对OOPObject Oriented Programming面向对象编程的补充和完善。
🍉欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁
🍉博主将持续更新学习记录收获友友们有任何问题可以在评论区留言
🍉博客中涉及源码及博主日常练习代码均已上传GitHub
📍内容导读📍
🍅1.面向切面编程AOP
1.1 什么是AOP
AOP(Aspect Oriented Programming)面向切面编程它是一种思想它是对某一类事情的集中处理。比如用户登录权限的效验没学AOP之前我们所有需要判断用户登录的页面中的方法都要各自实现或调用用户验证的方法然而有了AOP之后我们只需要在某一处配置一下所有需要判断用户登录页面中的方法就全部可以实现用户登录验证了不再需要每个方法中都写相同的用户登录验证了。
AOP是一种思想而Spring AOP这个框架是对AOP思想的实现它们的关系和IoC和DI类似。
1.2 AOP的作用
想象一个场景我们在做后台系统时除了登录和注册等几个功能不需要做用户登录验证之外其他几乎所有页面调用的前端控制器(Controller)都需要先验证用户登录的状态那么这个时候我们要怎么处理呢
如果不使用AOP我们之前的处理方式是每个Controller都要写一遍用户登录验证然而当你的功能越来越多那么你要写的登录验证也越来越多就有了很多重复的代码而且这些方法的代码修改和维护的成本就会很高。
如果使用AOP在进入业务代码之前进行统一的一个处理去验证用户是否登录。
除了统一的用户登录判断之外AOP还可以实现
- 统一日志记录
- 统一方法执行时间统计
- 统一的返回格式设置
- 统一的异常处理
- 事务的开启和提交
也就是说使用AOP可以扩充多个对象的某个能力所以AOP可以说是OOP(Object Oriented Programming)面向对象编程的补充和完善。
1.3 AOP基础组成
AOP由以下四部分组成
- 1.切面(Aspect)定义AOP业务类型表示当前AOP是做什么的。
- 2.连接点(Join Point)有可能调用AOP的地方就叫做一个连接点。
- 3.切点(Pointcut)定义AOP拦截规则。
- 4.通知(Advice)【增强方法】定义什么时候干什么事。
a) 前置通知在拦截的目标方法之前执行的通知事件
b后置通知在拦截的目标方法之后执行的通知事件
c返回之后通知在拦截的目标方法返回数据之后通知
d抛出异常之后的通知在拦截的目标方法抛出异常之后执行的通知
e环绕通知在拦截方法执行前后都执行的通知。
AOP整个组成部分的概念如下图所示以多个页面都要访问用户登录权限为例
🍅2.Spring AOP 实现
我们接下来使用Spring AOP来实现AOP的功能完成的目标是拦截所有UserController
里面的方法每次调用UserController
中任意一个方法时都执行相应的通知事件。
Spring AOP的具体实现步骤如下
2.1添加 Spring AOP 框架支持
在pom.xml
中添加如下配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.2定义切面和切点
切点指的是具体要处理的某一类问题比如用户登录权限验证就是一个具体的问题记录所有方法的执行日志就是一个具体的问题切点定义的是某一类问题。
具体实现如下
其中pointcut
方法为空方法其不需要方法体此方法名就是起到一个“标识”的作用标识下面的通知方法具体指的是哪个切点。
切点表达式说明
AspectJ支持三种通配符
*
匹配任意字符只匹配一个元素包类或方法方法参数
..
匹配任意字符可以匹配多个元素在表示类时必须和*
联合使用
+
表示按照类型匹配指定类的所有类必须跟在类名后面如com.cad.Car+
表示继承该类的所有子类包括本身
表达式示例如下
execution(* com.example.demo.UserController. *(..))
匹配UserController
类里的所有方法。execution(* com.example.demo.UserController+.*(..))
匹配UserController
类的子类包括该类的所有方法execution(* com.example.demo.*.*(..))
匹配com.example.demo
包下的所有类的所有方法execution(* com.example.demo..*.*(..))
匹配com.example.demo
包下、子孙包下所有类的所有方法execution(* addUser(String,int))
匹配addUser方法且第一个参数类型是String第二个参数类型是int
2.3定义通知
通知定义的是被拦截的方法具体要执行的业务比如用户登录权限验证方法就是具体要执行的业务。
Spring AOP中可以在方法上使用以下注解会设置方法为通知方法在满足条件后会通知本方法进行调用
a) 前置通知使用@Before在拦截的目标方法之前执行的通知事件
b后置通知使用@After在拦截的目标方法之后执行的通知事件
c返回之后通知使用@AfterReturning在拦截的目标方法返回数据之后通知
d抛出异常之后的通知使用@AfterThrowing在拦截的目标方法抛出异常之后执行的通知
e环绕通知使用@Around在拦截方法执行前后都执行的通知。
具体实现如下
@Component
@Aspect // 标识当前类为一个切面
public class LoginAop {
// 定义切点拦截的规则使用AspectJ表达式语法
@Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
public void pointcut() {
}
// 前置通知
@Before("pointcut()")
public void doBefore() {
System.out.println("执行了前置通知");
}
// 后置通知
@After("pointcut()")
public void doAfter() {
System.out.println("执行了后置通知");
}
// 环绕通知
@Around("pointcut()")
public Object doAround(ProceedingJoinPoint joinPoint) {
Object result=null;
// 前置业务代码
System.out.println("环绕通知的前置执行方法");
try {
// 执行目标方法
result=joinPoint.proceed();
}catch (Throwable e) {
e.printStackTrace();
}
// 后置业务执行代码
System.out.println("环绕通知的后置执行代码");
return result;
}
}
访问UserController
类中方法对应的URL控制台打印结果如下图
🍅3.Spring AOP 实现原理
Spring AOP是构建在动态代理基础上因此Spring 对AOP的支持局限于方法级别的拦截
Spring AOP支持 JDK Proxy 和 CGLIB 方式实现动态代理。默认情况下实现了接口的类使用AOP会基于JDK生成代理类没有实现接口的类会基于 CGLIB 生成代理类。
Spring AOP本质就是生成了一个目标对象的代理类当前端传来请求时不会将请求直接交给目标对象而是首先由代理类进行处理如果满足一定的条件才会将请求交给目标对象。
比如如果处理请求前需要登录验证那么代理类会去验证用户是否登录如果用户登录了才会将请求交给目标对象并执行核心业务代码否则代理类将返回响应让用户先登录。
🍅4.总结
AOP是对某方面能力的统一实现它是一种实现思想Spring AOP是对AOP的具体实现Spring AOP可通过AspectJ(注解)的方式来实现AOP的功能Spring AOP的实现步骤是
1.添加AOP框架支持
2.定义切面和切点
3.定义通知
Spring AOP是通过动态代理的方式在运行期将AOP代码织入到程序中的它的实现方式有两种JDK Proxy和CGLIB。
⭐️最后的话⭐️
总结不易希望uu们不要吝啬你们的👍哟(^U^)ノ~YO如有问题欢迎评论区批评指正😁