В моем весеннем приложении 5 MVC я включил AOP в своем сервлете-диспетчере xml, используя <aop:aspectj-autoproxy />
.Методы классов контроллера помечаются @PreAuthorize("hasAuthority('SOME_AUTH')")
.
Если я включаю AOP, метод hasAuthority () вызывает базу данных для проверки разрешения.
Если я отключаю AOP, hasAuthority () метод не вызывает базу данных для проверки разрешения, вместо этого он проверяет ее из самого контекста.
(Это мое наблюдение за включением журналов на уровне TRACE. С включенным AOP я вижу запросы для проверки разрешения на своей консоли. С отключенным AOP я не вижу запросов на своей консоли.)
Когда hasAuthority () начинает взаимодействовать с базой данных, я должен аннотировать метод контроллера с помощью @Transactional
, чтобы текущий сеанс базы данных был закрыт.Если я этого не сделаю, приложение перестает работать после нескольких успешных запросов, потому что все соединения используются, поскольку сеанс базы данных не закрыт.
Теперь проблема в том, что я не хочу аннотировать всеметоды контроллера (with @PreAuthorize()
) с @Transactional.Кроме того, я не хочу перемещать все методы hasAuthority () в пользовательский класс SecurityUtil, а затем заменять hasAuthority () на @securityUtil.hasAuthority()
.
Есть ли другой способ добиться этого без использования @Transactional наметоды моего контроллера ИЛИ есть ли способ заставить Spring Security проверять разрешение из контекста, а не из базы данных, когда AOP включен?
UPDATE
Запрос, сгенерированный hasAuthority (), выглядит следующим образом:
select this_.type as y0_, this_.key_id as y1_ from permission_master this_ where this_.status=? and this_.key_id in()
Класс SecurityExpressionRoot.java имеет метод hasAuthority (), который вызывает следующие методы в последовательности: hasAuthority () -> hasAnyAuthority () -> hasAnyAuthorityName-> getAuthoritySet () -> roleHierarchy.getReachableGrantedAuthorities ()
В нашей кодовой базе вызов roleHierarchy.getReachableGrantedAuthorities () был переопределен, поэтому я добавил @Transactional к переопределенному вызову и решил свою проблему.Но мой вопрос: почему включение AOP заставляет hasAuthority () вызывать базу данных, а отключение AOP - нет.