繁体   English   中英

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

[英]In Spring Boot AOP, how to get class annotation when in the method “Around” period?

感谢这里的所有朋友。 我知道如何获取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, IsAdmin annotation) throws Throwable {
  return commonIsAdmin(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返回类型(否则通知将不匹配这些方法,即使切入点本身匹配)。

所以如果一个around通知匹配是由切入点本身和返回类型的组合决定的。 您可以将其用作通过定义特定返回类型来限制切入点匹配的工具(然后您需要将proceed()的返回值强制转换为该类型,因为proceed()总是返回一个Object )。

顺便说一句,如果目标方法返回一个原始类型,如intboolean等,那么建议将自动包装结果为IntegerBoolean

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


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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM