需求:
? ? ? ? 針對查詢返回的數據,在數據庫層處理可能會影響到性能,在考慮性能及維護方便的情況下,采用AOP實現
1,自定義注解
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,定義公共業務處理接口
/*** 不同的業務場景 其 針對返回值 解析處理規則不同,須根據自身情況實現該接口* @param <T>*/
public interface MapperReturnDataInterface<R> {R transferReturnData(Object request);}
3,編寫AOP核心實現
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,編寫業務處理實現
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>>{@Overridepublic 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指定接口方法上使用
@MapperReturnData(operation = TechnologyGetDataTypeList.class)List<String> getDataTypeList(List<String> columnList);