您可以在Spring中使用方面更改方法的签名吗?
像有效地改变了以下内容:
@GetMapping("/thing")
@User // custom annotation that should authenticate the user
public ResponseEntity getThing() {
... // user is successfully authenticated, get the "thing" from the database
}
进入:
@GetMapping("/thing")
public ResponseEntity getThing(@CookieValue("Session-Token") String sessionToken) {
User user = authenticator.authenticateSessionTokenOrThrow(sessionToken);
... // user is successfully authenticated, get the "thing" from the database
}
变量user
也可以在方法主体中使用。
如果没有,如何在不重复代码(参数和身份验证器调用)的情况下达到相同的结果?
答案 0 :(得分:1)
不是为了这个。
是的,他们可以通过编译或运行时编织有效地修改.class
文件的字节码,但是不要覆盖方法的签名。
此外,默认的Spring AOP Aspects是用纯Java实现的,因此无法触及字节码层。为此,您需要AspectJ。
在运行/编译时用于自定义字节码的工具为ASM,ByteBuddy,CGLIB或Javassist。
但是,您可能可以通过Annotation Processor完成此操作,它可以让您修改实际的源而不是已经编译的字节码。
如果没有,如何在不重复代码的情况下达到相同的结果 (参数和身份验证器调用)无处不在?
可能的解决方案是
Exception
Exception
1很简单。
2比较耗时
3恕我直言,这似乎是身份验证的最佳选择,但这是最复杂的,可能是
HandlerInterceptor可以选择适用于哪些方法?
不幸的是,没有。几个月前,我要求使用Interceptor
仅“覆盖”某些方法,并且实现了一个自定义解决方案,该解决方案只是在方法本身上查找指定的注释。
这是我的自定义HandlerInterceptor
的摘录,它首先在类型上查找CheckInit
批注,然后在方法上查找更具体的自定义。
@Override
public boolean preHandle(
final HttpServletRequest request,
final HttpServletResponse response,
final Object handler
) throws Exception {
if (handler instanceof HandlerMethod) {
if (shouldCheckInit((HandlerMethod) handler)) {
checkInit();
}
}
return true;
}
private static boolean shouldCheckInit(final HandlerMethod handlerMethod) {
final var typeAnnotation = handlerMethod.getBeanType().getAnnotation(CheckInit.class);
final var shouldCheckInit = typeAnnotation != null && typeAnnotation.value();
final var methodAnnotation = handlerMethod.getMethodAnnotation(CheckInit.class);
return (methodAnnotation == null || methodAnnotation.value()) && shouldCheckInit;
}
private void checkInit() throws Exception {
if (!manager.isActive()) {
throw new NotInitializedException();
}
}
“标准Spring AOP建议”似乎很有趣,您是否有链接 为此吗?
Spring AOP documentation-寻找基于Java的配置(我讨厌XML)
AspectJ确实触及了字节码,还可以修改签名吗?
您可以使AspectJ修改签名。只需分叉项目并修改其Java代理或编译器即可。
AFAIK注释处理器无法修改类,它们只能 创建新的。
问题是,它们不修改.class
文件,而是修改源文件,这意味着他们只是对其进行编辑。例如。 Lombok使用注释处理来修改源文件。
但是,是的,修改后的源将写入新文件。