• Spring AOP使用


    Spring AOP是什么?

    AOP(面向切面编程):将那些与业务无关,却为业务模块所共同调用的逻辑(例如事务处理、日志管理、权限控制等)封装抽取成一个可重用的模块,这个模块被命名为“切面”(Aspect),便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性;

    在Spring AOP中,切面由切点(Pointcut)和通知(Advice)组成。切点是一个表达式,用于匹配哪些方法需要被横切,通知是在切点位置执行的代码,表示横切逻辑。

    切点表达式配置语法:
    execution(修饰符 返回值 包名称.类名称.方法名称(参数列表))
    execution(public void com.apesource.service.ServiceImp.findAll())

    1. 修饰符可以省略代表任意        execution(返回值 包名称.类名称.方法名称(参数列表))
    2. 返回值可以使用“*”代表任意        execution(* 包名称.类名称.方法名称(参数列表))
    3. 包名可以使用“*”代表任意名称        execution(* *.*.*.类名称.方法名称(参数列表))
    4. 包名可以使用“..”代表任意个数         execution(* *...类名称.方法名称(参数列表))
    5. 类名与方法名可以使用“*”代表任意        execution(* *...*.*(参数列表))
    6. 参数列表可以使用".."代表任意个数任意类型        execution(* *...*.*(..))

        如果有参数        int======>int        String===>java.lang.String

    Spring AOP提供了几种常见的通知类型,包括:

    • 前置通知(Before):在方法执行前执行的逻辑
    • 后置通知(After):在方法执行后执行的逻辑
    • 返回通知(After-returning):在方法成功返回后执行的逻辑
    • 异常通知(After-throwing):在方法抛出异常后执行的逻辑
    • 环绕通知(Around):在方法执行前后都可以执行的逻辑,可以控制目标方法的执行流程

    Spring AOP 基于动态代理实现:

    • 如果被代理的对象,已经实现某个接口,则 Spring AOP 会使用 JDK Proxy(反射),基于接口的方式,创建代理对象;
    • 如果被代理的对象,没有实现某个接口, Spring AOP 会使用 Cglib,基于继承的方式,生成一个被代理对象的子类来作为代理;

    Spring AOP可以通过注解或XML配置的方式来定义切点和通知,并且可以与Spring的IOC容器无缝集成,使得切面和目标对象的创建和管理变得更加简单。 

    1⃣️XML

    1.添加依赖:

    1. org.springframework
    2. spring-context
    3. 5.3.28
    4. org.aspectj
    5. aspectjweaver
    6. 1.9.7

    2.创建切面类:

    1. public class LoggerUtil {
    2. //前置通知
    3. public void beforeMethod(){
    4. System.out.println("前置通知=====>"+new Date());
    5. }
    6. //返回通知
    7. public void afterRrturnMethod(){
    8. System.out.println("返回通知=====>"+new Date());
    9. }
    10. //异常通知
    11. public void throwMethod(){
    12. System.out.println("异常通知=====>"+new Date());
    13. }
    14. //后置通知
    15. public void afterMethod(){
    16. System.out.println("后置通知=====>"+new Date());
    17. }
    18. //环绕通知
    19. public Object arroundMethod(ProceedingJoinPoint pjp){
    20. Object obj = null;
    21. try {
    22. //环绕通知---前置通知
    23. System.out.println("环绕通知---前置通知");
    24. Object[] objs = pjp.getArgs();
    25. obj = pjp.proceed(objs);
    26. //环绕通知---返回通知
    27. System.out.println("环绕通知---返回通知");
    28. } catch (Throwable throwable) {
    29. //环绕通知---异常通知
    30. System.out.println("环绕通知---异常通知");
    31. throwable.printStackTrace();
    32. } finally {
    33. //环绕通知---后置通知
    34. System.out.println("环绕通知---后置通知");
    35. }
    36. return obj;
    37. }
    38. }

    3.配置XML:

    1. <aop:config>
    2. <aop:aspect id="mian" ref="loggerUtil">
    3. <aop:pointcut id="dian" expression="execution(* *...*.*(..))"/>
    4. <aop:before method="beforeMethod" pointcut-ref="dian">aop:before>
    5. <aop:after-returning method="afterRrturnMethod" pointcut-ref="dian">aop:after-returning>
    6. <aop:after-throwing method="throwMethod" pointcut-ref="dian">aop:after-throwing>
    7. <aop:after method="afterMethod" pointcut-ref="dian">aop:after>
    8. <aop:around method="arroundMethod" pointcut-ref="dian">aop:around>
    9. aop:aspect>
    10. aop:config>

    2⃣️注解

    1.添加依赖:

    1. org.springframework
    2. spring-context
    3. 5.3.28
    4. org.aspectj
    5. aspectjweaver
    6. 1.9.7

    2.创建切面类:

    1. @Component
    2. @Aspect//切面
    3. //@EnableAspectJAutoProxy
    4. public class LoggerUtil {
    5. //切点
    6. @Pointcut(value="execution(* com.apesource.service.*.*(..))")
    7. public void dian(){}
    8. //前置通知
    9. // @Before("dian()")
    10. public void beforeMethod(){
    11. System.out.println("前置通知=====>"+new Date());
    12. }
    13. //返回通知
    14. // @AfterReturning("dian()")
    15. public void afterRrturnMethod(){
    16. System.out.println("返回通知=====>"+new Date());
    17. }
    18. //异常通知
    19. // @AfterThrowing("dian()")
    20. public void throwMethod(){
    21. System.out.println("异常通知=====>"+new Date());
    22. }
    23. //后置通知
    24. // @After("dian()")
    25. public void afterMethod(){
    26. System.out.println("后置通知=====>"+new Date());
    27. }
    28. //环绕通知
    29. @Around("dian()")
    30. public Object arroundMethod(ProceedingJoinPoint point){
    31. Object returnObj = null;//执行切点方法
    32. try {
    33. System.out.println("环绕通知====>前置通知");
    34. //切点
    35. Object[] obj = point.getArgs();//切点方法的参数
    36. returnObj = point.proceed(obj);
    37. System.out.println("环绕通知====>返回通知");
    38. } catch (Throwable throwable) {
    39. throwable.printStackTrace();
    40. System.out.println("环绕通知====>异常通知");
    41. } finally {
    42. System.out.println("环绕通知====>后置通知");
    43. }
    44. return returnObj;//切点方法的返回值
    45. }
    46. }

    3.配置XML:(也大可不配直接注解)

    1. <aop:aspectj-autoproxy>aop:aspectj-autoproxy>

  • 相关阅读:
    测试接触不到第一手需求,如何保证不漏测?
    【个人首测】百度文心一言 VS ChatGPT GPT-4
    5.3 Web服务器简介及HTTP协议
    5 款漏洞扫描工具:实用、强力、全面(含开源)
    讯飞有一个可以根据描述文本自动生成PPT的AI接口,有趣
    k8s集群中部署prometheus server
    液晶显示计算器(按键程序)
    from sklearn import cross_validation 报错的解决方法
    【Unity入门计划】Unity2D动画(2)-脚本与混合树实现玩家角色动画过渡
    CE修改植物大战僵尸-阳光基址(小宇特详解)
  • 原文地址:https://blog.csdn.net/lcannal/article/details/132909175