前言
開發程序的時候使用了aop去代理對象,然后其他地方會獲取到這個代理對象並獲取上面的方法注解和參數注解,運行時卻發現無法獲取注解,最終折騰一番終於解決。
原因
使用了AOP去進行代理,由於代理的對象不是接口,因此springboot會使用cglib去進行代理。
debug的時候可以看到,代理對象是由cglib代理的。

然后遍歷bean這個類的方法,依次獲取方法上的MessageMapping注解,獲取到就將其添加到map中
這里獲取注解的方法是AnnotatedElementUtils.getMergedAnnotation()
但是,發現本應能獲取到注解的方法,此時卻無法獲取到注解
通過debug繼續查看下去,發現方法上的注解全部為空

獲取方法上的注解
其實解決辦法非常簡單,只需要將上面獲取注解的代碼AnnotatedElementUtils.getMergedAnnotation()改為AnnotatedElementUtils.findMergedAnnotation()就能輕松解決
可以看到,通過這種方式可以成功獲取到方法上的注解,並且進入了if判斷

獲取方法參數上的注解
隨后需要獲取方法參數上的注解,同樣也是獲取為null

這個問題是比較棘手,試過SpringBoot內置的工具類,目前沒找到能正常獲取注解的方式。
因此決定換個思路,直接獲取cglib代理類的原始對象,獲取原始對象上的參數注解就可以了
直接上代碼
private Parameter getProxySourceMethodParameter(Class<?> clazz, Method method, Integer parameterIndex) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException {
boolean isCglibProxyClass = clazz.getName().contains("$$");
if (!isCglibProxyClass) {
return ArrayUtil.get(method.getParameters(), parameterIndex);
}
Class<?> sourceClass = clazz.getSuperclass();
String methodName = method.getName();
Class<?>[] methodParameterTypes = method.getParameterTypes();
Method sourceMethod = sourceClass.getDeclaredMethod(methodName, methodParameterTypes);
return ArrayUtil.get(sourceMethod.getParameters(), parameterIndex);
}
通過獲取原始類的方法參數,然后再獲取參數上的注解就可以解決了。
Parameter parameter = getProxySourceMethodParameter(clazz, method, paramIndex);
Ref ref = AnnotatedElementUtils.findMergedAnnotation(parameter, Ref.class);
