Spring AOP @Pointcut и @Before приводит к исключению IllegalArgumentException: ошибка в:: 0 формальное несвязанное в pointcut

#java #spring #spring-boot #aspectj #spring-aop

Вопрос:

Я занимаюсь проектом springboot, который включает в себя логин и учетные записи. Я пытаюсь выполнить @Pointcut все вызовы методов контроллера и проверить информацию для входа, а @Before также вырезать точки, чтобы убедиться, что сеанс существует. Отсюда и код:

 @Aspect
@Component
public class AuthAspect {
    Logger logger = LoggerFactory.getLogger(AuthAspect.class);

    @Pointcut("execution(* show.xianwu.game.frisbeescorer.controller.*.*(..))")
    public void validateLogin(JoinPoint joinPoint) {
        // check the login information
    }

    @Before("validateLogin()")
    public void validateSession(JoinPoint joinPoint) {
        // check the session
    }
}
 

Однако это дает org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'projectingArgumentResolverBeanPostProcessor' defined in class path resource [org/springframework/data/web/config/ProjectingArgumentResolverRegistrar.class]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: error at ::0 formal unbound in pointcut свои результаты .

Удаление validateSession() и @Before делает @Pointcut работу. Как я могу это исправить?

Комментарии:

1. Удалите JoinPoint из своего @Pointcut аннотированного метода.

2. @Power_tile, пожалуйста, будьте настолько вежливы, чтобы оставлять отзывы о комментариях и ответах, которые другие пользователи потратили на написание для вас здесь. В идеале примите адекватный ответ по вашему собственному выбору. Спасибо.

Ответ №1:

Проблема в том, что вы определяете JoinPoint параметр в точечном разрезе. Это относится только к методу рекомендаций, использующему точечный разрез, а не к самому точечному разрезу. Вы все равно не используете его там, потому что точечный разрез никогда не выполняется, метод-это просто пустышка, которую нужно украсить @Poinctut аннотацией. Итак, чего ты хочешь, так это:

 @Pointcut("execution(* show.xianwu.game.frisbeescorer.controller.*.*(..))")
public void validateLogin() {
    // check the login information
}
 

Кроме того (и не имеет отношения к вашей проблеме), .*.* это довольно специфично и соответствует только методу в классе, который точно находится в пакете show.xianwu.game.frisbeescorer.controller . Если вы также хотите включить классы в подпакеты, .. в данном случае вместо этого используйте синтаксис show.xianwu.game.frisbeescorer.controller..* .

Ответ №2:

Поскольку вы работаете над проектом на основе Springboot, я рекомендую вам использовать функции безопасности Spring или другие системы авторизации и аутентификации, такие как Shiro.

Если вы все равно не хотите использовать ни один из них, вы можете использовать @ModelAttributes в суперклассе для вызова метода до вызова любого метода контроллера.

 @Controller
public class ExampleController extends BaseController {...}
 
 public class BaseController {
    @ModelAttribute
    public void invokeBefore(HttpServletRequest request,
                        HttpServletResponse response) {
         // Check the auth info (e.g., Authorization header) of the request.
    }
}
 

Кроме того, по моему опыту, это плохая практика для непосредственного использования @Pointcut в приложении SpringBoot. Вместо этого используйте настроенную аннотацию Spring.

Комментарии:

1. Проверки подлинности и т. Д. Не относятся к контроллеру, они должны либо находиться в фильтре, который будет выполняться задолго до чего-либо еще, либо применяться через AOP. Это слишком легко ломается. Единственное, что хорошо, — это использовать Spring Security, которая является проверенной и проверенной платформой, не пытайтесь внедрить свое собственное решение для обеспечения безопасности.

2. Правда. В этом я согласен с мсье Дейном. Как правило, если позволяет время, я предпочитаю иметь отдельное приложение шлюза, где я могу выполнять аутентификацию и авторизацию в фильтрах. Даже если мне придется поместить все в одно приложение Springboot, я бы использовал Shiro для фильтрации запросов до того, как какой-либо запрос попадет на контроллеры.

3. Это не отвечает на вопрос ОП.