AOP的使用

本文详细介绍了SpringBoot中AOP(面向切面编程)的概念、JDK/CGLIB动态代理的区别、关键术语以及实战示例。涵盖切面、连接点、切入点、目标对象和通知等概念,并展示了如何使用@Before、@After和@Around注解进行不同类型的拦截操作,包括日志记录和异常通知功能。
摘要由CSDN通过智能技术生成

基础概念

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,在实际业务中,可以用来做非核心增强功能. 如日志,通知等.

SpringBoot 实现 Aop 的两种方式:
1) JDK 动态代理 需要一个接口
2) CGLIB 不需要接口
区别: JDK动态代理是面向接口的。
CGLib动态代理是通过字节码底层继承要代理类来实现,因此如果被代理类被final关键字所修饰,会失败。
速度方面 JDK动态代理更快
springboot使用方式 : 根据场景切换

5个重要概念:
1) 切面(Aspect) : 泛指交叉业务逻辑,如日志
2) 连接点(JoinPoint) : 被切入的具体方法,具体业务接口的方法均为连接点
3) 切入点(Pointcut) : 指声明的一个或多个连接点集合,通常指一组方法
4) 目标对象(Target) : 需要被增强的对象, 即包含主业务逻辑类的对象
5) 通知(Advice) : 切面的切入时间

代码示例

定义一个切入点

/**  
 * 截取对象 :  
 * @Pointcut 就是切入点  
 * 切入点表达式逻辑: (1:访问权限类型 2:返回值类型 s:包名类名(参数类型和个数 使用" .. "替代 抛出异常)  
 *  通常使用 execution (* com.e6.fengtianwen.aopdemo.controller.*.*(..))方式基本可以解决大部分场景  
 */  
@Pointcut("execution (* com.xx.xxx.aopdemo.controller.*.*(..))")  
public void exceptionAdvice() {  
    
}

使用切入点定义一个执行前拦截

/**  
 * 进入方法前执行  
 * Before 就是通知类型  通知(Advice)  
 */
 @Before("exceptionAdvice()")  
public void beforeAdvice() {  
   System.out.println("beforeAdvice...");  
   System.out.println("第一种切入点使用方式");  
   System.out.println("-----------------");  
}

重要的切片注解:
@Before:执行方法前,切片
@After: 执行方法后,切片
@Around: 环绕拦截,既可以进入前操作,又可以执行方法后切片

例子,使用@Around做拦截输出:

/**  
 *使用环绕注解做方法执行时间统计,超过一定的时间,  
 * 被认为是bug,发送邮件通知程序员回来加班  
 * @param pjp 连接点  
 * @return  
 * @throws Throwable  
 */
@Around("exceptionAdvice()")  
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {  
  
   // 进入方法之前  
   TimeInterval timer = DateUtil.timer();  
   // 连接点 : 注意返回  
   //请求的 类名、方法名  
   Signature signature = pjp.getSignature();  
   String className = pjp.getTarget().getClass().getName();  
   String methodName = signature.getName();  
  
   Object proceed = pjp.proceed();  
   long spendTime = timer.intervalSecond();  
   // 进入方法之后  
   log.info("该访问一共花费: " + spendTime + " s");  
  
   // 场景: 请求过长导致程序崩溃,通知上线修BUG  
   if(spendTime >= MAX_REQUEST_TIME){  
      String title = "【重要通知Aop项目出现BUG, 级别-严重】";  
      String content = "主人程序崩溃了,快起床修 BUG !\n <br> <br> <strong> "            + "接口位置 : "+className + "." +methodName + " </strong><br>  <br> <strong style=\"color:red;\"> 时间: " + DateUtil.now() + "</strong>";  
  
      log.error("【重要级别-Bug】接口位置 : " + className + " " +methodName);  
  
      MailUtilFromHutool.send("xxx@xxx.com",title,content);  
   }  
   return proceed;  
}

其他用例:

使用AOP+注解

/**  
 * 添加拦截注解  
 * @param pjp 切入点  
 * @param controllerLog  被拦截的注解对象,通过该对象可以获取被拦截的数据  
 * @throws Throwable  
 */@After(value = "@annotation(controllerLog)")  
public void doAfter(JoinPoint pjp, MyLog controllerLog)throws Throwable {  
  
   String value = controllerLog.value();  
  
   log.info("获得注解值: " + value );  
  
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值