AOP-@Around环绕增强-理解问题-测试-记录

发布时间 2023-12-01 15:10:29作者: gjkt_2001

来源

自定义注解测试切面环绕时,接口测试返回空白。

理解

关键在于:环绕增强后走的是切面类中的方法,你不给返回值(习惯void)就是空白=-=。

@Around

它可以包围一个方法或函数的执行,并在执行前后提供额外的逻辑
使用@Around注解,你可以定义一个通知(advice),该通知在目标方法执行之前和之后运行。这种通知可以用于日志记录、性能监控、安全检查、事务管理等场景。(自定义实现业务逻辑)

ProceedingJoinPoint类

ProceedingJoinPoint是Spring AOP中的一个重要类,用于表示一个切点(pointcut)的执行上下文。它封装了目标方法的调用,并提供了一种方式来执行目标方法并获取其返回值。

ProceedingJoinPoint的主要方法是proceed(),该方法会执行目标方法并返回其结果。(解析响应码、报错信息存日志等等)
其它方法:

  • getSignature():返回目标方法的签名(Signature)对象,可以用于获取方法名称、参数类型等信息。
  • getThis():返回目标对象(即被代理的对象),如果该对象为null,则返回代理对象。
  • getArgs():返回目标方法的参数列表。(解决不同类型入参对象的字段获取->可定义转换接口,入参泛化,注解反射带Class。)

解决

如代码。

/**
 * 切面类
 */
@Component
@Aspect
public class csAspct {
    @Pointcut("@annotation(com.xyz66.AOP.annotation.cs)")
    public void pointcut() {
    }
    
    @Around("pointcut()")
    public Object before(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("------Around环绕前--------");
        Signature signature = joinPoint.getSignature();// 得到签名
        MethodSignature methodSignature = (MethodSignature) signature;// 强转为方法签名
        Method method = methodSignature.getMethod();// 得到方法
        cs annotation = method.getAnnotation(cs.class);// 得到注解
        System.out.println("注解的value为:"+annotation.value());// 输出注解的值
        // 关键点!!!
        Object proceed = joinPoint.proceed();// 执行目标方法并返回其结果
        System.out.println(JSON.toJSONString(proceed));
        System.out.println("------Around环绕后--------");
        return proceed;
    }
}

记录

AOP切面的步骤:

  1. 定义切入点
  2. 横切逻辑
  3. 织入

实习记录:
记录日志,不想影响程序主链路性能,采用异步,搞一个线程池去跑(阻塞队列)。

    private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            1,1,1, TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>(1000)
    );// 异步去跑

设计字段存在二种方式

  1. 先写代码实体类再设计表
  2. 先设计表再写实体类(也是后端玩)
    谁开发,谁设计;
    谁设计,谁背锅;
    谁背锅,谁修复;
    谁修复,谁开发。

解决不同类型入参对象的字段获取:
少就别定义接口,直接判断(instanceof)->强转。

/**  
 * 不同参数类型处理  
 * @param aName  
 * @param args  
 * @return String 参数对象字段-名称  
 */  
private static String assessmentType(String aName, Object[] args) {  
    for (Object arg : args) {  
        // 不同参数类型处理  
        if (arg instanceof XXXDTO){  
            // 强转
            XXXDTO cXXXDTO = (XXXDTO) arg;  
            aName = cXXXDTO.getXXXXName();  
        }  
        else if(arg instanceof AppraiseObjectDTO){  
            // 继续判断转
        }  
    }  
    return aName;  
}

service层业务不一定强迫症保证单一职责原则,要的可以组合成一个service提高效率。