自定义注解和切面的结合使用:
1、自定义注解
// 1 定义注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SelfAnnotation {
/**
* 注解内的参数1
* @return string
*/
String paramFirst();
/**
* 注解内的参数2
* @return string
*/
String paramSecond() default "";
}
// 使用
@SelfAnnotation(paramFirst = "#dto.param", paramSecond = Constant.A)
public R<?> dealRelation(@RequestBody ReqDTO dto){
// 代码业务
}
2、切面
@Slf4j
@Aspect
@Component
public class SelfAnnotationAspect {
@Resource
private ISelfAnnotationClient client;
private final ExpressionParser parser = new SpelExpressionParser();
public SelfAnnotationAspect() {
}
@After("@annotation(selfAnnotation)")
public void after(JoinPoint joinPoint, SelfAnnotation self) throws Throwable {
try {
StandardEvaluationContext context = new StandardEvaluationContext(joinPoint.getArgs());
// 解析方法入参中的DTO
setContextVariables(context, joinPoint);
// 参数1依赖方法传入的DTO进行取值,需要用new SpelExpressionParser()来解析
Object paramFirst = parser.parseExpression(self.paramFirst()).getValue(context);
// 参数2是一个常量,不需要解析传入的DTO,可以直接获取到
String paramSecond = self.paramSecond();
// 业务逻辑方法,自行定义
client.doBusiness(client.getAEntity(value.toString(), self.paramFirst(), paramSecond));
} catch (Exception e) {
log.info("记录异常", e);
}
}
// 解析方法入参中的DTO
private void setContextVariables(StandardEvaluationContext standardEvaluationContext,
JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method targetMethod = methodSignature.getMethod();
LocalVariableTableParameterNameDiscoverer parameterNameDiscoverer
= new LocalVariableTableParameterNameDiscoverer();
String[] parametersName = parameterNameDiscoverer.getParameterNames(targetMethod);
if (args == null || args.length <= 0) {
return;
}
for (int i = 0; i < args.length; i++) {
standardEvaluationContext.setVariable(parametersName[i], args[i]);
}
}
}