自定义注解
- 自定义
DistributeExceptionHandler
注解,该注解接收一个参数attachmentId
。
- 该注解用在方法上,使用该注解作为切点,实现标注该注解的方法抛异常后的统一处理。
/**
* @Author: Lijian
* @Date: 2019-09-06 09:26
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributeExceptionHandler {
String attachmentId();
}
@DistributeExceptionHandler(attachmentId = "#test.id")
public void test(Test test){
}
Aspect
代码
- 拦截
DistributeExceptionHandler
注解作为切点
- 使用
@AfterThrowing
处理异常情况
/**
* @Author: Lijian
* @Date: 2019-09-06 09:22
*/
@Component
@Aspect
@Slf4j
public class DistributeExceptionAspect {
@Autowired
private AttachmentContentClient attachmentContentClient;
@Autowired
private DistTaskService distTaskService;
private ExpressionEvaluator<String> evaluator = new ExpressionEvaluator<>();
@Pointcut("@annotation(DistributeExceptionHandler)")
private void exceptionHandleMethod() {
}
@AfterThrowing(value = "exceptionHandleMethod()", throwing = "ex")
public void doThrowing(JoinPoint joinPoint, Throwable ex) {
log.error("捕获异常");
String attachmentId = getAttachmentId(joinPoint); // 获取
// 处理异常情况下的业务
}
private DistributeExceptionHandler getDistributeExceptionHandler(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
return method.getAnnotation(DistributeExceptionHandler.class);
}
private String getAttachmentId(JoinPoint joinPoint) {
DistributeExceptionHandler handler = getDistributeExceptionHandler(joinPoint);
if (joinPoint.getArgs() == null) {
return null;
}
EvaluationContext evaluationContext = evaluator.createEvaluationContext(joinPoint.getTarget(), joinPoint.getTarget().getClass(), ((MethodSignature) joinPoint.getSignature()).getMethod(), joinPoint.getArgs());
AnnotatedElementKey methodKey = new AnnotatedElementKey(((MethodSignature) joinPoint.getSignature()).getMethod(), joinPoint.getTarget().getClass());
return evaluator.condition(handler.attachmentId(), methodKey, evaluationContext, String.class);
}
}
为注解添加Spring EL支持
/**
* @Author: Lijian
* @Date: 2019-09-06 09:26
*/
public class ExpressionRootObject {
private final Object object;
private final Object[] args;
public ExpressionRootObject(Object object, Object[] args) {
this.object = object;
this.args = args;
}
public Object getObject() {
return object;
}
public Object[] getArgs() {
return args;
}
}
/**
* @Author: Lijian
* @Date: 2019-09-06 09:26
*/
public class ExpressionEvaluator<T> extends CachedExpressionEvaluator {
private final ParameterNameDiscoverer paramNameDiscoverer = new DefaultParameterNameDiscoverer();
private final Map<ExpressionKey, Expression> conditionCache = new ConcurrentHashMap<>(64);
private final Map<AnnotatedElementKey, Method> targetMethodCache = new ConcurrentHashMap<>(64);
public EvaluationContext createEvaluationContext(Object object, Class<?> targetClass, Method method, Object[] args) {
Method targetMethod = getTargetMethod(targetClass, method);
ExpressionRootObject root = new ExpressionRootObject(object, args);
return new MethodBasedEvaluationContext(root, targetMethod, args, this.paramNameDiscoverer);
}
public T condition(String conditionExpression, AnnotatedElementKey elementKey, EvaluationContext evalContext, Class<T> clazz) {
return getExpression(this.conditionCache, elementKey, conditionExpression).getValue(evalContext, clazz);
}
private Method getTargetMethod(Class<?> targetClass, Method method) {
AnnotatedElementKey methodKey = new AnnotatedElementKey(method, targetClass);
Method targetMethod = this.targetMethodCache.get(methodKey);
if (targetMethod == null) {
targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
if (targetMethod == null) {
targetMethod = method;
}
this.targetMethodCache.put(methodKey, targetMethod);
}
return targetMethod;
}
}
备注