Аспекты не предназначены для этого.
Да, они могут эффективно изменять .class
байт-код файлов, с компиляцией времени компиляции или времени выполнения, но они не переопределяют сигнатуры методов.
Кроме того, аспекты Spring AOP по умолчанию реализованы на чистом Java и поэтому не могут касаться уровня байт-кода. Для этого вам понадобится AspectJ.
Инструменты для настройки байт-кода во время выполнения / компиляции: ASM , ByteBuddy , CGLIB или Javassist.
Однако , вы, вероятно, можете сделать это с помощью Процессора аннотаций , который позволяет вам изменять фактические источники вместо уже скомпилированного байт-кода.
Если нет, как я могу достичь того же результата, не повторяя код
(вызов параметра и аутентификатора) везде?
Возможные решения
- HandlerInterceptor , который просто выбрасывает
Exception
, если пользователь не аутентифицирован
- Стандартный совет Spring AOP, который просто выдает
Exception
, если пользователь не аутентифицирован
- Spring Security
1 довольно просто.
2 занимает больше времени
3 imho, кажется, лучше всего подходит для аутентификации, но оно самое сложное, вероятно
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 advice" кажется интересным, у вас есть ссылка
за что?
Документация Spring AOP - ищите конфигурацию на основе Java (я ненавижу XML)
AspectJ действительно касается байт-кода и может также изменять сигнатуры?
Вы можете заставить AspectJ изменять сигнатуры. Просто разветвите проект и измените его Java-агент или компилятор.
Процессоры аннотаций AFAIK не могут изменять классы, они могут только
создавать новые.
Дело в том, что они не изменяют файлы .class
, вместо этого они изменяют исходные файлы, что означает, что они просто редактируют их. Например. Lombok использует обработку аннотаций для изменения исходных файлов.
Но да, измененные источники записываются в новый файл.