Spring Aop 实现对mapper层入参进行重新赋值

需求描述:

需要对mapper查询的入参的某个属性值进行特殊处理后查询

不影响原来业务且方便扩展维护

1,自定义注解

java 复制代码
import java.lang.annotation.*;

/**
 * 针对 mapper层入参 按照一定规则进行特殊处理重新赋值
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MapperRequestData {
    /**
     * 指定执行规则的方法,默认方法为:transferRequestData
     * @return
     */
    String method() default "transferRequestData";
    Class<? extends MapperRequestDataInterface> operation();
}

2,定义动态处理指定业务的接口

java 复制代码
/**
 * 不同的业务场景 其 针对入参 解析处理规则不同,须根据自身情况实现该接口
 * @param <T>
 */
public interface MapperRequestDataInterface {

    void transferRequestData(Object request);

}

3,定义切面 MapperRequestDataAspect

java 复制代码
import com.taia.yms.aop.reponse.inter.MapperRequestDataInterface;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;

/**
 * 针对 mapper层入参进行特殊处理
 */
@Component
@Aspect
public class MapperRequestDataAspect {
    private static final Logger log = LoggerFactory.getLogger(MapperRequestDataAspect.class);
    //定义pointcut签名
    @Pointcut("execution(* com.taia.yms.mapper.*.*(..)) && @annotation(com.taia.yms.aop.reponse.MapperRequestData)")
    private void pointCut() {
        //方法为空,仅做签名
    }

    //对切点方法进行前置增强,就是在调用切点方法前进行做一些必要的操作,这就成为增强
    @Before("pointCut()")
    public void getRes(JoinPoint joinPoint){
        // 获取方法签名
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        MapperRequestData annotation = method.getAnnotation(MapperRequestData.class);
        Object[] objects = joinPoint.getArgs();
        // 查找并获取注解
        try{
            // 读取注解的属性
            Class<? extends MapperRequestDataInterface> operation = annotation.operation();
            MapperRequestDataInterface operationInstance = operation.getDeclaredConstructor().newInstance();
            String methoded = annotation.method();
            Method operationMethod = operation.getDeclaredMethod(methoded, Object.class);
            operationMethod.invoke(operationInstance, objects);
        }catch (Exception e){
            log.error("类[{}]的方法[{}]执行失败,报错:{}",annotation.operation().getName(),annotation.method(),e.getMessage());
        }
    }

}

4,定义指定业务指定入参处理逻辑

java 复制代码
import com.taia.yms.aop.reponse.inter.MapperRequestDataInterface;
import com.taia.yms.entity.reqbody.TechnologyPageReqBody;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.stream.Collectors;

public class TechnologySelectConfigListReqRule implements MapperRequestDataInterface {
    private static final String PREFIX_SRE = "CONTAINS_";
    @Override
    public void transferRequestData(Object request) {
        TechnologyPageReqBody pageReqBody = (TechnologyPageReqBody) request;
        if(pageReqBody == null || CollectionUtils.isEmpty(pageReqBody.getDataTypeList())){
            return;
        }
        List<String> list = pageReqBody.getDataTypeList();
        List<String> collect = list.stream().map(v -> PREFIX_SRE + v).collect(Collectors.toList());
        pageReqBody.setDataTypeList(collect);
    }
}

5,相关对象类

java 复制代码
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import com.taia.yms.entity.ExportPageReqBody;
import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class TechnologyPageReqBody extends ExportPageReqBody{
    private Long id;
    private String fab;
    private String productId;
    private String technology;
    private List<String> dataTypeList;
    private String createdByName;
    private String lastUpdatedByName;
    // ALL、为空、不为空 all isNull  isNotNull
    private String isNullable;
}
java 复制代码
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.List;

/**
 * @ClassName ExportPageReqBody
 * 导出 和 分页数据
 **/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class ExportPageReqBody {
    /**页码*/
    @ApiModelProperty(example = "1")
    private Integer pageNum = 1;
    /**页面大小*/
    @ApiModelProperty(example = "10")
    private Integer pageSize = 10;

    /**1-导出excel, 0-导出CSV*/
    private String isExcel;
    /**1-只导出表头,0或空-导出表头和数据*/
    private String isEmpty;
    /**1-配置数据, 0或空-待添加配置数据*/
    private String isConfig;
    /**选择导出,有值时只导出选中的id*/
    private List<Long> selectedIds;
    /**当前登录用户的userId*/
    private String userNo;
}

6,在对应mapper层的对应方法加添加使用

java 复制代码
    /**
     * 查询已配置数据(支持字段模糊查询)
     */
    @MapperRequestData(operation = TechnologySelectConfigListReqRule.class)
    List<WipProductInfoTab> selectConfigList(TechnologyPageReqBody technologyPageReqBody);
相关推荐
小小娥子1 分钟前
Redis的基础认识与在ubuntu上的安装教程
java·数据库·redis·缓存
几何心凉8 分钟前
已解决:org.springframework.web.HttpMediaTypeNotAcceptableException
java
华农第一蒟蒻11 分钟前
Java中JWT(JSON Web Token)的运用
java·前端·spring boot·json·token
两点王爷12 分钟前
使用WebClient 快速发起请求(不使用WebClientUtils工具类)
java·网络
计算机学姐24 分钟前
基于SpringBoot+Vue的高校运动会管理系统
java·vue.js·spring boot·后端·mysql·intellij-idea·mybatis
平凡的小码农38 分钟前
JAVA实现大写金额转小写金额
java·开发语言
一直在进步的派大星41 分钟前
Docker 从安装到实战
java·运维·docker·微服务·容器
老华带你飞1 小时前
公寓管理系统|SprinBoot+vue夕阳红公寓管理系统(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·spring boot·课程设计
我明天再来学Web渗透1 小时前
【hot100-java】【二叉树的层序遍历】
java·开发语言·数据库·sql·算法·排序算法
结衣结衣.1 小时前
python中的函数介绍
java·c语言·开发语言·前端·笔记·python·学习