• 【Sprig AOP】


    目录

    🥗1 AOP 的思想

    🍚2 AOP 的组成

    🥚2.1 切面

    🍙3 AOP 的实现

    🍤3.1 添加 Spring AOP 依赖

    🥫3.2 定义切面

    🍣3.3 定义切点

    🍳3.4 实现通知

    🍔4 AOP 实现的一个例子


    1 AOP 的思想

    机场里有多家公司,但是安检是进候机室之前统一安排的,不需要不同航空公司各自安排一次安检。在计算机领域,也有类似的思想——AOP。

    AOP(Aspect Oriented Programming):⾯向切⾯编程,它是⼀种思想,它是对某⼀类事情的集中处理。⽐如⽤户登录权限的效验,没学 AOP 之前,我们所有需要判断⽤户登录的⻚⾯(比如博客系统,所有需要用户登录的页面),都要各⾃实现或调⽤⽤户验证的⽅法,然⽽有了 AOP 之后,我们只需要在某⼀处配置⼀下,所有需要判断⽤户登录⻚⾯就全部可以实现⽤户登录验证了,不再需要每个页面都写相同的⽤户登录验证了。

    AOP 是⼀种思想,⽽ Spring AOP 是⼀个框架,实现了 AOP 思想,两者之间的关系很像 MVC 与 Spring MVC 。

    2 AOP 的组成

    2.1 切面

    切⾯(Aspect)由切点(Pointcut)和通知(Advice)组成。

    切面:定义事件,也就是规定 AOP 要处理什么。比如用户登录效验

    切点:定义具体规则,比如用户登录的拦截规则

    通知:AOP 执行的具体方法,比如获取用户登录信息,如果已获取到说明已经登录了,否则就是未登录状态。

    三者之间的关系类似于,公司的老板决定公司的业务是什么,而中层则来制定如何做事情的规则,最后由底层的劳动人民来实施具体的工作。

    3 AOP 的实现

    3.1 添加 Spring AOP 依赖

    引入 Spring AOP 依赖:

    1. org.springframework.boot
    2. spring-boot-starter-aop

    3.2 定义切面

    切面是一个类。需要两个注解。一个是 @Aspect ,表明该类是一个切面。

    要让切面随着项目的启动而启动,因此要添加六大注解之一。这样才不会让那些在切面中定义的切点等方法,失去用处。

    1. @Aspect //表明这个类是个 切面
    2. @Component // 需要六大注解之一,以便在程序启动的时候便启动
    3. public class UserAspect {
    4. ......
    5. }

    3.3 定义切点

    切点表达式由切点函数组成,其中 execution() 是最常⽤的切点函数,⽤来匹配⽅法,语法为:

    execution(<修饰符><返回类型><包名+类名+方法(参数)><异常>)

    修饰符和异常通常可以省略。* 表示任意。 

    拦截 包名+类名 的所有方法的返回值

    1. // 切点
    2. // 包名 + 类名
    3. @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
    4. public void pointcut(){
    5. }

    3.4 实现通知

    通知的方法:

    前置通知使⽤@Before:通知⽅法会在⽬标⽅法调⽤之前执⾏。 后置通知使⽤

    @After:通知⽅法会在⽬标⽅法返回或者抛出异常后调⽤。 返回之后通知使⽤@AfterReturning:通知⽅法会在⽬标⽅法返回后调⽤。 抛异常后通知使⽤@AfterThrowing:通知⽅法会在⽬标⽅法抛出异常后调⽤。 环绕通知使⽤

    @Around:通知包裹了被通知的⽅法,在被通知的⽅法通知之前和调⽤之后执 ⾏⾃定义的⾏为。

    4 AOP 实现的一个例子

    1. package com.example.demo.controller;
    2. import org.springframework.web.bind.annotation.RequestMapping;
    3. import org.springframework.web.bind.annotation.RestController;
    4. @RestController
    5. @RequestMapping("/user")
    6. public class UserController {
    7. @RequestMapping("/getuser")
    8. public String getUser(){
    9. System.out.println("do getUser");
    10. return "get user";
    11. }
    12. }
    1. package com.example.demo.controller;
    2. import org.springframework.web.bind.annotation.RequestMapping;
    3. import org.springframework.web.bind.annotation.RestController;
    4. @RestController
    5. @RequestMapping("/art")
    6. public class ArticleController {
    7. @RequestMapping("/getart")
    8. public String getArticle(){
    9. System.out.println("do getArticle");
    10. return "getArticle";
    11. }
    12. }

    1. package com.example.demo.common;
    2. import org.aspectj.lang.annotation.After;
    3. import org.aspectj.lang.annotation.Aspect;
    4. import org.aspectj.lang.annotation.Before;
    5. import org.aspectj.lang.annotation.Pointcut;
    6. import org.springframework.context.annotation.EnableAspectJAutoProxy;
    7. import org.springframework.stereotype.Component;
    8. @Aspect //表明这个类是个 切面
    9. @Component // 需要六大注解之一,以便在程序启动的时候便启动
    10. public class UserAspect {
    11. // 切点
    12. // 包名 + 类名
    13. @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
    14. public void pointcut(){
    15. }
    16. // 前置通知
    17. // 需要指定切点的方法名,针对那个切点做出的具体方法实现。
    18. @Before("pointcut()")
    19. public void doBefore(){
    20. System.out.println("执行了前置通知");
    21. }
    22. // 后置通知
    23. @After("pointcut()")
    24. public void doAfter(){
    25. System.out.println("执行了后置通知");
    26. }
    27. // 环绕通知
    28. // 接受的参数类型一定是 ProceedingJoinPoint ,写死的
    29. @Around("pointcut()")
    30. public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
    31. System.out.println("环绕通知执行之前");
    32. // 执行目标方法
    33. Object result = joinPoint.proceed();
    34. System.out.println("环绕通知执行之后");
    35. return result;
    36. }
    37. }


  • 相关阅读:
    redis底层数据结构
    【CSS】头部尾部固定中间滚动
    DAIR-V2X-V 3D检测数据集 转为Kitti格式 | 可视化
    【算法】高精度加、减、乘、除(C++实现)
    java毕业生设计高考志愿智能辅助填报系统计算机源码+系统+mysql+调试部署+lw
    设计模式-装饰器模式
    AAOS音频路由 问题分析
    Sophus库使用笔记
    Eclipse Python IDE安装
    【从零开始学习 SystemVerilog】3.8、SystemVerilog 控制流—— Tasks(任务)
  • 原文地址:https://blog.csdn.net/qq_41233305/article/details/132620892