问题描述
感谢这里的所有朋友。我知道如何获取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();
}
解决方法
您可能已经注意到,您无法将来自不同||
分支的信息绑定到通知方法参数,因为它可能是模棱两可的,另请参阅我的回答here和here。因此,如果您想避免丑陋(且缓慢)的反映,请执行我在其他答案中建议的操作,并写出两条截然不同的建议,如果您在这里担心避免代码重复,则将通用代码分解为辅助方法。这样的东西(未经测试,只是为了让您对代码结构有所了解):
@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
强制转换为该返回类型)
顺便说一句,如果目标方法返回诸如int
,boolean
等的原始类型,则建议将自动将结果包装为Integer
或{{1} }。
您真的应该阅读Spring AOP和AspectJ手册或教程,因为我在这里解释了可以在此处找到的内容。
更新:OP要求提供有关参数绑定的文档以及描述如何确定名称的描述:
- 您可以为所有建议类型指定一个
Boolean
参数,例如argNames
,@Before
,@After
。 - 如果缺少该注释参数,则Spring AOP将尝试通过类文件调试信息(如果已编译)来匹配建议方法参数名称。否则,在这种情况下匹配将失败。
- 当使用带有编译时编织功能的完整AspectJ而不是Spring AOP时,确定名称也无需调试信息,因为AspectJ编译器可以在编译期间确定必要的信息。
所有这些都在Spring AOP manual中进行了描述。
,通过反射获取类,通过类获取固定的方法信息,并获取方法上的注释。这样,您应该能够反映出