aop 获取参数并修改返回值

@Aspect
@Component
public class AsyncPageAop {

    /**
     * 定义切入点,用于匹配带有 @PreProcess 注解的方法。
     */
    @Pointcut("@annotation(com.arpa.wms.common.asyncPage.AsyncPage)")
    public void AsyncPage() {
    }

    /**
     * 在方法调用前进行处理,修改请求参数。
     * @param joinPoint 连接点对象
     * @return 修改后的返回结果
     * @throws Throwable 异常
     */
    @Around("AsyncPage() && @annotation(modifyReturnValueAnnotation)")
    public Object modifyParam(ProceedingJoinPoint joinPoint, AsyncPage modifyReturnValueAnnotation) throws Throwable {
        long startTime = System.currentTimeMillis();
        // 1.获取请求参数
//        Object[] args = joinPoint.getArgs();
//        Object arg = args[0];
//        // 2.查询selectType
//        Field selectTypeField = arg.getClass().getDeclaredField("selectType");
//        selectTypeField.setAccessible(true);
//        Object selectTypeValue = selectTypeField.get(arg);
       
        System.out.println("Select Type: " + selectType);
//        JSONObject jsonData = JSONObject.parseObject(JSON.toJSONString(arg));
//        System.out.println(jsonData.get("selectType"));
//        String selectType=String.valueOf(jsonData.get("selectType"));
        // 获取注解属性值
        String annotationValue = modifyReturnValueAnnotation.value();
        System.out.println("Annotation Value: " + annotationValue);
        // 根据入参修改返回值
        if (AsyncPageEnum.RECORDS.getValue().equals(selectType)&&AsyncPageEnum.RECORDS.getValue().equals(annotationValue)) {
            System.out.println("判断完成进入方法执行:"+ (System.currentTimeMillis() - startTime) + "ms" + StringUtil.NEWLINE);
            Object result = joinPoint.proceed();
            return result;
        }else if (AsyncPageEnum.RECORDS.getValue().equals(selectType)&&AsyncPageEnum.COUNT.getValue().equals(annotationValue)) {
            Object modelInstance  =null;
            MethodSignature methodSignature  = (MethodSignature) joinPoint.getSignature();
            // 被切的方法
            Method method = methodSignature.getMethod();
            // 返回类型
            Class<?> methodReturnType = method.getReturnType();
            System.out.println(methodReturnType);
            // 实例化
           Map<String, Object> attributes = new HashMap<>();
           attributes.put("total", 0L);
           modelInstance = methodReturnType.getDeclaredConstructor().newInstance();
           setModelAttributes(modelInstance, attributes);
            System.out.println("判断完成返回count:"+(System.currentTimeMillis() - startTime) + "ms" + StringUtil.NEWLINE);
            System.out.println(modelInstance);
            return modelInstance;
        }else if (AsyncPageEnum.COUNT.getValue().equals(selectType)&&AsyncPageEnum.COUNT.getValue().equals(annotationValue)) {
            System.out.println("判断完成进入方法执行:"+(System.currentTimeMillis() - startTime) + "ms" + StringUtil.NEWLINE);
            Object result = joinPoint.proceed();
            return result;
        } else if (AsyncPageEnum.COUNT.getValue().equals(selectType)&&AsyncPageEnum.RECORDS.getValue().equals(annotationValue)) {
            System.out.println("判断完成返回list:"+(System.currentTimeMillis() - startTime) + "ms" + StringUtil.NEWLINE);
            return new ArrayList<>();
        }
        // 调用目标方法,并获取返回值
        Object result = joinPoint.proceed();
        return result;
    }



    public void setModelAttributes(Object model, Map<String, Object> attributeMap) throws Exception {
        Class<?> modelClass = model.getClass();
        for (Map.Entry<String, Object> entry : attributeMap.entrySet()) {
            String propertyName = entry.getKey();
            Object propertyValue = entry.getValue();
            try {
                Field field = modelClass.getDeclaredField(propertyName);
                field.setAccessible(true);  // 设置为可访问
                field.set(model, propertyValue);  // 给属性赋值
            } catch (NoSuchFieldException e) {
                // 如果属性不存在,可以根据实际情况处理异常
                e.printStackTrace();
            }
        }
    }


}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AsyncPage {
    String value() default "";
}

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 AOP 技术拦截并修改 SQL 语句的步骤如下: 1. 配置 AOP:在 Spring 配置文件中配置 AOP,指定要拦截的切点(Pointcut)和要执行的通知(Advice)。例如,可以使用 AspectJ 注解来定义切点和通知: ```java @Aspect public class SqlInterceptor { @Pointcut("execution(* org.example.dao.*.*(..))") public void daoMethods() {} @Around("daoMethods()") public Object interceptSql(ProceedingJoinPoint joinPoint) throws Throwable { String sql = getSql(joinPoint); // 修改 SQL 语句 String modifiedSql = modifySql(sql); // 记录日志 logSql(modifiedSql); // 执行 SQL 语句 return joinPoint.proceed(); } private String getSql(ProceedingJoinPoint joinPoint) { // 获取 SQL 语句 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); String sql = getSqlFromAnnotation(method); if (sql == null) { sql = getSqlFromStatement(method); } return sql; } // ... } ``` 上述代码定义了一个名为 "SqlInterceptor" 的切面(Aspect),包含一个名为 "daoMethods" 的切点和一个名为 "interceptSql" 的通知。切点指定了要拦截的 DAO 方法,通知使用 "Around" 类型,并在方法执行前后执行一些操作,例如获取 SQL 语句、修改 SQL 语句、记录日志等。 2. 实现通知逻辑:在通知方法中,可以使用反射等方式获取 DAO 方法的参数返回值、注解等信息,然后根据这些信息生成或修改 SQL 语句。例如,可以使用 JSqlParser 等工具来解析 SQL 语句,然后修改其中的条件、表名、列名等信息。 ```java private String modifySql(String sql) { Statement statement = CCJSqlParserUtil.parse(sql); if (statement instanceof Select) { Select select = (Select) statement; // 修改 SELECT 语句中的列名 List<SelectItem> selectItems = select.getSelectItems(); for (SelectItem item : selectItems) { if (item instanceof SelectExpressionItem) { SelectExpressionItem expressionItem = (SelectExpressionItem) item; Expression expression = expressionItem.getExpression(); if (expression instanceof Column) { Column column = (Column) expression; column.setColumnName("modified_" + column.getColumnName()); } } } return select.toString(); } else if (statement instanceof Update) { Update update = (Update) statement; // 修改 UPDATE 语句中的表名 Table table = update.getTable(); table.setName("modified_" + table.getName()); return update.toString(); } else { return sql; } } ``` 上述代码使用 JSqlParser 解析 SQL 语句,并修改其中的列名或表名,然后返回修改后的 SQL 语句。需要注意的是,不同类型的 SQL 语句需要使用不同的方式进行修改。 3. 调用 DAO 方法:在通知方法中,调用原始的 DAO 方法,执行修改后的 SQL 语句,或者将修改后的 SQL 语句传递给下一个拦截器。如果需要执行多个拦截器,可以使用环绕通知(Around Advice),在通知方法中调用 joinPoint.proceed() 方法,将控制权传递给下一个拦截器或 DAO 方法。 上述代码实现了拦截并修改 SQL 语句的功能,可以根据实际需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值