需求:
针对查询返回的数据,在数据库层处理可能会影响到性能,在考虑性能及维护方便的情况下,采用AOP实现
1,自定义注解
java
import java.lang.annotation.*;
/**
* 针对 mapper层返回值 按照一定规则进行特殊处理后返回
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MapperReturnData {
/**
* 指定执行规则的方法,默认方法为:transferReturnData
* @return
*/
String method() default "transferReturnData";
Class<? extends MapperReturnDataInterface> operation();
}
2,定义公共业务处理接口
java
/**
* 不同的业务场景 其 针对返回值 解析处理规则不同,须根据自身情况实现该接口
* @param <T>
*/
public interface MapperReturnDataInterface<R> {
R transferReturnData(Object request);
}
3,编写AOP核心实现
java
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
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 MapperReturnDataAspect {
private static final Logger log = LoggerFactory.getLogger(MapperReturnDataAspect.class);
//定义pointcut签名
@Pointcut("execution(* com.taia.yms.mapper.*.*(..)) && @annotation(com.taia.yms.aop.reponse.MapperReturnData)")
private void pointCut() {
//方法为空,仅做签名
}
//对切点方法进行前置增强,就是在调用切点方法前进行做一些必要的操作,这就成为增强
@Around("pointCut()")
public Object getRes(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取被拦截的方法签名
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 获取被拦截的方法
Method method = signature.getMethod();
// 获取返回值
Object returnObj = joinPoint.proceed();
MapperReturnData annotation = method.getAnnotation(MapperReturnData.class);
// 查找并获取注解
try{
// 读取注解的属性
Class<? extends MapperReturnDataInterface> operation = annotation.operation();
MapperReturnDataInterface operationInstance = operation.getDeclaredConstructor().newInstance();
String methoded = annotation.method();
Method operationMethod = operation.getDeclaredMethod(methoded, Object.class);
return operationMethod.invoke(operationInstance,returnObj);
}catch (Exception e){
log.error("类[{}]的方法[{}]执行失败,报错:{}",annotation.operation().getName(),annotation.method(),e.getMessage());
return returnObj;
}
}
}
4,编写业务处理实现
java
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class TechnologyGetDataTypeList implements MapperReturnDataInterface<List<String>>{
@Override
public List<String> transferReturnData(Object request) {
List<String> list = (List<String>) request;
if(CollectionUtils.isEmpty(list)){
return new ArrayList<>(1);
}
List<String> results = list.stream()
.map(v -> v.substring(v.indexOf("_")+1))
.collect(Collectors.toList());
return results;
}
}
5,在mapper指定接口方法上使用
java
@MapperReturnData(operation = TechnologyGetDataTypeList.class)
List<String> getDataTypeList(List<String> columnList);