写点什么

springboot 实现 AOP 切面编程

  • 2021 年 11 月 11 日
  • 本文字数:2125 字

    阅读完需:约 7 分钟

AOP 的通知类型


  • 前置通知 : 在目标类的方法执行之前执行。

  • 配置文件信息:<aop: before method=“before” pointcut-ref=“myPointcut3”/>

  • 应用:可以对方法的参数来做校验

  • 最终通知 : 在目标类的方法执行之后执行,如果程序出现了异常,最终通知也会执行。

  • 在配置文件中编写具体的配置:<aop:after method=“after” pointcut-ref=“myPointcut3”/>

  • 应用:例如像释放资源

  • 后置通知 : 方法正常执行后的通知。

  • 在配置文件中编写具体的配置:<aop:after-returning method=“afterReturning” pointcut-ref=“myPointcut2”/>

  • 应用:可以修改方法的返回值

  • 异常抛出通知 : 在抛出异常后通知

  • 在配置文件中编写具体的配置:<aop:after-throwing method=“afterThorwing” pointcut-ref=“myPointcut3”/>

  • 应用:包装异常的信息

  • 环绕通知: 方法的执行前后执行。环绕通知使用灵活.其他方式都能用环绕方式实现。

  • 在配置文件中编写具体的配置:<aop:around method=“around” pointcut-ref=“myPointcut2”/>

  • 要注意:目标的方法默认不执行,需要使用 ProceedingJoinPoint 对来让目标对象的方法执行。

使用 aspectj 实现 AOP 功能

在 pom.xml 中引入依赖:


<dependency>


<groupId>org.springframework</groupId>


<artifactId>spring-aop</artifactId>


<version>5.0.8.RELEASE</version>


</dependency>


<dependency>


<groupId>org.aspectj</groupId>


<artifactId>aspectjrt</artifactId>


<version>1.8.9</version>


</dependency>


<dependency>


<groupId>org.aspectj</groupId>


<artifactId>aspectjweaver</artifactId>


<version>1.8.9</version>


</dependency>


方式一:

import lombok.extern.slf4j.Slf4j;


import org.aspectj.lang.JoinPoint;


import org.aspectj.lang.ProceedingJoinPoint;


import org.aspectj.lang.annotation.*;


import org.springframework.core.annotation.Order;


import org.springframework.stereotype.Component;


@Component


//注解表明这是一个 AspectJ 文件,编译器在编译的时候,就会自动去解析,然后将代码注入到相应的 JPonit 中。


@Aspect //必须的注解


@Order(-1)


public class AOPDemo {


@Pointcut(value = "execution(* com.controller.update(..))")


private void beforePointcut(){


//切面,方法里的内容不会执行


}


@Before(value = "beforePointcut()")


public void before(JoinPoint joinPoint){


//@Before 是在方法执行前无法终止原方法执行


System.out.println("前置通知。。。"+


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


joinPoint);


}


@Pointcut(value = "execution(* com.controller.save(..))")


private void afterReturningPointcut(){}


@AfterReturning(value = "afterReturningPointcut()",returning = "result")


public void afterReturning(Object result){


System.out.println("后置通知。。。"+result);


}


@Pointcut(value = "execution(* com.controller.delete(..))")


private void aroundPointcut(){}


@Around(value = "aroundPointcut()")


public Object around(ProceedingJoinPoint joinPoint) throws Throwable {


//用 @Around 用环绕通知可以拒绝可以放行


System.out.println("环绕通知。。。");


Object obj = joinPoint.proceed();


System.out.println("环绕通知。。。");


return obj;


}


@Pointcut(value = "execution(* com.controller.findOne(..))")


private void afterThrowingPointcut(){}


@AfterThrowing(value = "afterThrowingPointcut()",throwing = "e")


public void afterThrowing(Throwable e){


System.out.println("异常抛出通知"+e.getMessage());


}


@Pointcut(value = "execution(* com.controller.findAll(..))")


private void afterPointcut(){}


//|| 关联多个切面


@After(value = "afterPointcut() || afterReturningPointcut()")


public void after(){


System.out.println("最终通知");


}


}


  • execution: 处理 JPoint 的类型,例如 call,execution


例如定义切入点表达式 execution (* com.sample.service.impl…*. *(…)) 整个表达式可以分为五个部分:


1、execution(): 表达式主体。


2、第一个*号:表示返回类型, *号表示所有的类型。


3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl 包、子孙包下所有类的方法。


4、第二个*号:表示类名,*号表示所有的类。


5、*(…):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数


_多个切点例如:


@Before("execution (_ android.app.Activity.onCreate(…)) ||execution (* android.app.Activity.onDestroy()) "


JoinPoint 对象



JoinPoint 对象封装了 SpringAop 中切面方法的信息,在切面方法中添加 JoinPoint 参数,就可以获取到封装了该方法信息的 JoinPoint 对象.


常用 api:



  • Signature getSignature(); 获取封装了署名信息的对象,在该对象中可以获取到目标方法名,所属类


Class等信息


  • Object[] getArgs(); 获取传入目标方法的参数对象


  • Object getTarget(); 获取被代理的对象


  • Object getThis(); 获取代理对象



ProceedingJoinPoint 对象



ProceedingJoinPoint 对象是 JoinPoint 的子接口,该对象只用在 @Around 的切面方法中,

评论

发布
暂无评论
springboot实现AOP切面编程