在Spring Boot AOP中,如何在“ Around”方法期间获取类注释?

问题描述

感谢这里的所有朋友。我知道如何获取method上设置的注释的注释参数。

虽然我想在Class添加注释。如何在AOP Around方法中从Class中检索属性

顺便说一句,我还有一个问题,为什么我需要将响应值从void更改为Object并返回pjp.proceed()。如果该方法没有响应,则请求将冻结。

对于具有HasRole批注的方法

@Around("@annotation(com.example.demo.aspect.annotation.HasRole) && @annotation(annotation)")
public void aroundHasRole(ProceedingJoinPoint pjp,HasRole annotation) throws Throwable {

    log.info("value->>{}",annotation.value());
    pjp.proceed();

}

对于具有HasRole注释的类或方法

@Around("(@within(com.example.demo.aspect.annotation.IsAdmin)"
        + "|| @annotation(com.example.demo.aspect.annotation.IsAdmin))")
public Object aroundHasRole(ProceedingJoinPoint pjp) throws Throwable {

    <<How to get annotation information here?>>
    return pjp.proceed();

}

解决方法

您可能已经注意到,您无法将来自不同||分支的信息绑定到通知方法参数,因为它可能是模棱两可的,另请参阅我的回答herehere。因此,如果您想避免丑陋(且缓慢)的反映,请执行我在其他答案中建议的操作,并写出两条截然不同的建议,如果您在这里担心避免代码重复,则将通用代码分解为辅助方法。这样的东西(未经测试,只是为了让您对代码结构有所了解):

@Around("@within(annotation)")
public Object classIsAdmin(ProceedingJoinPoint pjp,IsAdmin annotation) throws Throwable {
  return commonIsAdmin(pjp,annotation);
}

@Around("@annotation(annotation)")
public Object methodIsAdmin(ProceedingJoinPoint pjp,annotation);
}

public Object commonIsAdmin(ProceedingJoinPoint pjp,IsAdmin annotation) throws Throwable {
  // Here you would place all common advice code.
  // Non-common code could remain in the original advice methods.
  log.info("value->>{}",annotation.value());
  return pjp.proceed();
}

为什么我需要将响应值从void更改为Object并返回pjp.proceed()。如果该方法没有响应,则请求将冻结。

@Before@After通知相反,在@Around通知中,您可以通过不调用proceed()来完全跳过目标方法的执行,从而修改返回值或者丢弃或修改proceed()的结果。您完全可以随意返回任何内容,只需匹配目标方法的返回类型即可。

已经说过,应该清楚的是,周围建议方法还必须具有与其截获的目标方法相匹配的返回类型。如果您的建议针对的是许多没有通用超级类型的类型,则它可以是像MyType这样的精确类型,超级类型,也可以是Object(所有类型的超级类型)。当(且仅当)所有目标方法也返回void时,建议也可以具有void的返回类型(否则,建议即使与切入点匹配也不会与这些方法匹配)

因此,围绕建议是否匹配取决于切入点本身和返回类型的组合。您可以通过定义特定的返回类型将其用作限制切入点匹配的工具(由于proceed()总是返回proceed(),因此您需要将其返回值Object强制转换为该返回类型)

顺便说一句,如果目标方法返回诸如intboolean等的原始类型,则建议将自动将结果包装为Integer或{{1} }。

您真的应该阅读Spring AOP和AspectJ手册或教程,因为我在这里解释了可以在此处找到的内容。


更新:OP要求提供有关参数绑定的文档以及描述如何确定名称的描述:

  • 您可以为所有建议类型指定一个Boolean参数,例如argNames@Before@After
  • 如果缺少该注释参数,则Spring AOP将尝试通过类文件调试信息(如果已编译)来匹配建议方法参数名称。否则,在这种情况下匹配将失败。
  • 当使用带有编译时编织功能的完整AspectJ而不是Spring AOP时,确定名称也无需调试信息,因为AspectJ编译器可以在编译期间确定必要的信息。

所有这些都在Spring AOP manual中进行了描述。

,

通过反射获取类,通过类获取固定的方法信息,并获取方法上的注释。这样,您应该能够反映出