java - 如何在springboot / java app中使用给定注释获取方法
问题描述
有没有办法直接获取在给定对象中使用给定注释注释的方法(非静态)?我不想遍历所有方法的列表并检查给定的注释是否存在。在下面的示例代码中,我使用了虚拟方法(不存在)getMethodAnnotatedWith()。我需要用实际方法替换它。
public class MyController {
@PostMapping("/sum/{platform}")
@ValidateAction
public Result sum(@RequestBody InputRequest input, @PathVariable("platform") String platform) {
log.info("input: {}, platform: {}", input, platform);
return new Result(input.getA() + input.getB());
}
}
class InputRequest {
@NotNull
private Integer a;
@NotNull
private Integer b;
@MyValidator
public boolean customMyValidator() {
log.info("From customMyValidator-----------");
return false;
}
}
@Aspect
@Component
@Slf4j
public class AspectClass {
@Before(" @annotation(com.example.ValidateAction)")
public void validateAspect(JoinPoint joinPoint) throws Throwable {
log.info(" MethodName : " + joinPoint.getSignature().getName());
Object[] args = joinPoint.getArgs();
log.info("args[0]==>"+args[0] +", args[1]==>"+args[1]);
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Parameter[] parameters = method.getParameters();
Method customMyValidator = parameters[0].getType().getMethodAnnotatedWith(MyValidator.class); // InputRequest class type which has a method annotated with @MyValidator
customMyValidator.invoke(args[0]);
}
}
解决方案
MethodUtils (Apache Commons Lang) 可用于实现需求。
示例代码中使用的 API:MethodUtils.getMethodsListWithAnnotation
方面代码
@Component
@Aspect
public class CallAnnotatedMethodAspect {
@Pointcut("within(rg.so.q64604586.service.*) && @annotation(rg.so.q64604586.annotation.ValidateAction)")
public void validateActionMethod() {
};
@Before("validateActionMethod() && args(request,..)")
public void adviceMethod(InputRequest request)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
List<Method> methodList = MethodUtils.getMethodsListWithAnnotation(request.getClass(), MyValidator.class);
for (Method m : methodList) {
m.invoke(request, new Object[] {});
}
}
}
注意:注释的保留策略MyValidator
是 RUNTIME 以使此代码正常工作。
如果InputRequest
切面中获取的实例是代理,则需要修改代码以获取相同的实际类。
推荐阅读
- programming-languages - 阶乘计算
- sql - 如何仅更改连接字符串?
- xslt - 来自外部文档的 XSLT 副本
- python - 调用 cuInit CUDA_ERROR_NOT_INITIALIZED 失败(设备映射:没有已知设备)Tensorflow-gpu 1.2.1
- javascript - 使用 Google 登录按钮退出网站
- c# - 如何在 Web 应用程序中读取另一个驱动器上的目录中的文件列表?
- python-3.x - 如何通过在没有循环的每一行上使用函数来创建新的 numpy 数组
- java - 为什么删除根节点会保留左子树而不保留我的右子树?
- vue.js - Vue从服务器接收数据
- html - 键盘 TAB 选择不可见