做网站赚谁的钱,广州番禺网站公司,通河县机场建设网站,怎么网上宣传自己的产品一、Spring AOP
AOP 是一种思想#xff0c;而 Spring AOP 是一个框架#xff0c;提供了一种对 AOP 思想的实现。
1、什么是 AOP#xff1f;
AOP#xff08;Aspect Oriented Programming#xff09;#xff1a;是一种编程思想#xff0c;表示面向切面编程。指的是对某…一、Spring AOP
AOP 是一种思想而 Spring AOP 是一个框架提供了一种对 AOP 思想的实现。
1、什么是 AOP
AOPAspect Oriented Programming是一种编程思想表示面向切面编程。指的是对某一类事情的集中处理。 举一个常见的例子当我们实现用户登录校验的时候如果有多个网页都有同样的需求那么我们传统的写法是在每个页面都写一个校验逻辑这就会导致代码的可维护性降低。而如果我们使用 AOP 的思想就可以对这种功能一致且多次使用的功能进行统一的处理。 通过上面的例子我们可以归纳出 AOP 的应用场景 统一的用户登录判断统一日志记录统一方法执行时间统计统一的返回格式设置统一的异常处理事务的开启和提交等 对于 AOP 来说它可以扩充多个对象的某个能力因此通常认为 AOP 是 OOPObject Oriented Programming面向对象编程的补充和完善。
2、AOP 的组成
切面Aspect定义的是事件描述了当前 AOP 的作用。是包含了 切点和通知 的类。例如定义当前AOP是进行统一用户登录判断的。
连接点Join Point连接点是在应用程序执行过程中可以插入切面的点切面代码可以利用这些点插入到应用的正常流程之中并添加新的行为。典型的连接点包括方法调用、方法执行、异常抛出等。
切点Pointcut定义匹配 Join Point 的规则给满足规则的 Join Point 添加 Advice。例如定义哪些接口判断用户登录权限哪些不判断。
通知AdviceAOP 执行方法的具体实现 。例如通过获取用户的 session 信息判断用户登录状态。
在Spring AOP 中提供了以下五种类型的通知 前置通知Before通知方法会在目标方法调用之前执行。后置通知After通知方法会在目标方法返回或者抛出异常后调用。返回通知AfterReturning通知方法会在目标方法返回后调用。异常通知AfterThrowing通知方法会在目标方法抛出异常后调用。环绕通知Around通知包裹了被通知的方法在被通知的方法通知之前和调用之后执行自定义的行为。 二、Spring AOP 实现
下面我们使用 Spring AOP 来完成拦截所有 UserController 里的方法每次调用 UserController 中任意一个方法时都执行相应的通知事件。
1、添加 AOP 框架支持
!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop --
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId
/dependency2、定义切面类
定义切面使用的是 Aspect
Aspect
Component
public class UserAspect {}3、定义切点
定义切点使用 Pointcut 注解可在参数中定义匹配 Joint Point 的规则这里使用的是 AspectJ 语法
Aspect
Component
public class UserAspect {// 定义切点使用 AspectJ 语法// 该切点规则将匹配 com.example.demo.controller.UserController 类// 中的所有方法无论方法的返回类型和参数列表如何Pointcut(execution(* com.example.demo.controller.UserController.*(..)))public void pointCut(){}
}4、实现通知
对于 前置通知、后置通知、返回通知、异常通知 的实现都如出一辙并且非常简单只需要添加给通知方法添加响应通知注解即可
Aspect
Component
public class UserAspect {// 定义切点使用 AspectJ 语法Pointcut(execution(* com.example.demo.controller.UserController.*(..)))public void pointCut(){}// 前置通知Before(pointCut())public void doBefore(){System.out.println(执行doBefore()前置通知!);}// 后置通知After(pointCut())public void doAfter(){System.out.println(执行doAfter()后置通知!);}// 返回通知AfterReturning(pointCut())public void doAfterReturn(){System.out.println(执行doAfterReturn()了返回通知);}// 异常通知AfterThrowing(pointCut())public void doAfterThrowing(){System.out.println(执行了doAfterThrowing()异常通知);}}比较复杂的是环回通知的实现环回通知有它固定的格式
Aspect
Component
public class UserAspect {// 定义切点使用 AspectJ 语法Pointcut(execution(* com.example.demo.controller.UserController.*(..)))public void pointCut() {}// 环绕通知Around(pointCut())public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println(Around ⽅法开始执⾏);// 执行目标方法Object obj joinPoint.proceed();System.out.println(Around ⽅法结束执⾏);return obj;}
}其中 ProceedingJoinPoint 在环绕通知中可以控制目标方法的执行。通过调用 joinPoint.proceed() 可以触发目标方法的执行。如果目标方法有返回值当目标方法执行完毕后它会被保存在 obj 变量中作为整个环绕通知方法的返回值返回给调用方。
调用 UserController 中的方法得到测试结果 三、Spring AOP 实现原理
Spring AOP 是构建在动态代理基础上的。Spring 的切面是由包裹了目标对象的代理实现的代理类处理方法的调用执行额外的切面逻辑并调用目标方法。
Spring AOP 支持 JDK Proxy 动态代理和 CGLIB 动态代理技术它们主要有以下区别 JDK Proxy 来自于 Java 本身CGLIB 来自于第三方。JDK Proxy 动态代理是基于接口的要求代理类必须实现接口才能实现代理CGLIB 动态代理是基于类的通过继承被代理类完成动态代理因此要求被代理类不能是 final 修饰的类。在 JDK 8 以上的版本中JDK Proxy 动态代理做了专门的优化所以性能比 CGLIB 高。