在 Spring 引导应用程序中捕获带有 aspect 的注释参数
Capturing annotated parameter with aspect in Spring boot application
对于 aspect,我正在尝试捕获带注释的参数,但它不起作用。
注释如下:
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DTO {}
服务class我在几个方法中标注了参数如下:
@Service
class MyService {
public MyDTO update(@DTO MyDTO myDTO) {
// ...
}
}
现在借助 aspect,我正尝试如下捕获那些带注释的参数:
@Aspect
class MyAspect {
// ...
@Before(value = "applicationServicePointcut()", argNames = "joinPoint")
public Object process(ProceedingJoinPoint joinPoint, StateManagement stateManagement)
throws Throwable {
// ...
// HERE I AM ALWAYS GETTING NULL
Object object = getAnnotatedParameter(joinPoint, DTO.class);
// ...
}
public Object getAnnotatedParameter(JoinPoint joinPoint, Class<?> annotatedClazz) {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Parameter[] params = methodSignature.getMethod().getParameters();
for (Parameter param : params) {
if (isParamAnnotatedWith(param, annotatedClazz.getName()))
{
return param;
}
}
return null;
}
private boolean isParamAnnotatedWith(Parameter param, String annotationClassName) {
for (Annotation annotation : param.getAnnotations()) {
System.out.println("Annotation class name : " + annotation.getClass().getName());
// HERE IN annotation.getClass().getName() I am getting com.sun.proxy.$Proxy375
if (annotation.getClass().getName().equals(annotationClassName)) {
return true;
}
}
return false;
}
}
我对如何用 aspect 捕获带注释的参数一无所知。有人可以在这里帮忙吗?谢谢
首先,如果我是你,我会将 Class<?>
的注释类型从 getAnnotatedParameter
传递到 isParamAnnotatedWith
以使处理更容易。
您代码中的实际错误是您在注释实例上使用了 getClass()
,它总是产生一个 JDK 动态代理 class,因为这是它内部的内容Java。相反,您应该使用方法 annotationType()
,它可以满足您的需求。
public Object getAnnotatedParameter(JoinPoint joinPoint, Class<?> annotationType) {
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
for (Parameter parameter : method.getParameters()) {
if (isParamAnnotatedWith(parameter, annotationType))
return parameter;
}
return null;
}
private boolean isParamAnnotatedWith(Parameter parameter, Class<?> annotationType) {
for (Annotation annotation : parameter.getAnnotations()) {
if (annotation.annotationType().equals(annotationType))
return true;
}
return false;
}
对于 aspect,我正在尝试捕获带注释的参数,但它不起作用。
注释如下:
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DTO {}
服务class我在几个方法中标注了参数如下:
@Service
class MyService {
public MyDTO update(@DTO MyDTO myDTO) {
// ...
}
}
现在借助 aspect,我正尝试如下捕获那些带注释的参数:
@Aspect
class MyAspect {
// ...
@Before(value = "applicationServicePointcut()", argNames = "joinPoint")
public Object process(ProceedingJoinPoint joinPoint, StateManagement stateManagement)
throws Throwable {
// ...
// HERE I AM ALWAYS GETTING NULL
Object object = getAnnotatedParameter(joinPoint, DTO.class);
// ...
}
public Object getAnnotatedParameter(JoinPoint joinPoint, Class<?> annotatedClazz) {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Parameter[] params = methodSignature.getMethod().getParameters();
for (Parameter param : params) {
if (isParamAnnotatedWith(param, annotatedClazz.getName()))
{
return param;
}
}
return null;
}
private boolean isParamAnnotatedWith(Parameter param, String annotationClassName) {
for (Annotation annotation : param.getAnnotations()) {
System.out.println("Annotation class name : " + annotation.getClass().getName());
// HERE IN annotation.getClass().getName() I am getting com.sun.proxy.$Proxy375
if (annotation.getClass().getName().equals(annotationClassName)) {
return true;
}
}
return false;
}
}
我对如何用 aspect 捕获带注释的参数一无所知。有人可以在这里帮忙吗?谢谢
首先,如果我是你,我会将 Class<?>
的注释类型从 getAnnotatedParameter
传递到 isParamAnnotatedWith
以使处理更容易。
您代码中的实际错误是您在注释实例上使用了 getClass()
,它总是产生一个 JDK 动态代理 class,因为这是它内部的内容Java。相反,您应该使用方法 annotationType()
,它可以满足您的需求。
public Object getAnnotatedParameter(JoinPoint joinPoint, Class<?> annotationType) {
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
for (Parameter parameter : method.getParameters()) {
if (isParamAnnotatedWith(parameter, annotationType))
return parameter;
}
return null;
}
private boolean isParamAnnotatedWith(Parameter parameter, Class<?> annotationType) {
for (Annotation annotation : parameter.getAnnotations()) {
if (annotation.annotationType().equals(annotationType))
return true;
}
return false;
}