背景: 公司内部服务之间调用走RPC框架,服务端提供sdk即可,所以暴露出去的都是 service层接口,但是也有统一封装返回结构体的需求,所以用到了AOP切面
用法: service 方法的 实现上加注解 @ApiExceptionPack 即可
import java.lang.annotation.*;
/**
* @description API异常处理。使用了当前注解的方法在抛出异常统一处理返回 Result对象
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface ApiExceptionPack {
}
AOP实现
/**
* @description 接口异常拦截处理
*/
@Slf4j
@Aspect
@Component
public class RequestLogAspect {
@Around("@annotation(com.xxx.ApiExceptionPack)")
public Object doRequestLog(ProceedingJoinPoint joinPoint) throws Throwable {
Signature signature = joinPoint.getSignature();
Object proceed = null;
try {
proceed = joinPoint.proceed(joinPoint.getArgs());
} catch (Exception e) {
log.warn("RequestLogAspect method: {}.{} params: {}, throw exception : ", signature.getDeclaringTypeName(), signature.getName(),
JSONObject.toJSONString(joinPoint.getArgs()), e);
//回滚事务
Method method = getMethod(joinPoint);
if (method == null || !method.getReturnType().isAssignableFrom(Result.class)) {
//返回类型不为 Result不处理,抛出异常
throw e;
}
proceed = Result.fail(ResultCode.SERVER_ERROR.getCode(), e == null || StringUtils.isBlank(e.getMessage()) ? "系统异常,请稍后重试" : e.getMessage());
//事务回滚
transactionRollback(method);
}
return proceed;
}
/***
* @Description 事务回滚
* @Param [joinPoint, method]
* @return void
*/
private void transactionRollback(Method method) {
try {
Transactional transactional = method.getAnnotation(Transactional.class);
if (transactional != null) {
//手动回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
} catch (Exception e) {
log.warn("RequestLogAspect transactionRollback throw Exeception :", e);
}
}
/**
* @return java.lang.reflect.Method
* @Description 获取Method
* @Param [joinPoint]
*/
private Method getMethod(ProceedingJoinPoint joinPoint) {
try {
String methodName = joinPoint.getSignature().getName();
Class<?> classTarget = joinPoint.getTarget().getClass();
Class<?>[] param = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
Method objMethod = classTarget.getMethod(methodName, param);
return objMethod;
} catch (Exception e) {
log.warn("RequestLogAspect getMethod throw Exeception :", e);
}
return null;
}
}