Spring AOP @Pointcut 和@Before 产生 IllegalArgumentException: error at ::0 formal unbound in pointcut
Spring AOP @Pointcut and @Before yields IllegalArgumentException: error at ::0 formal unbound in pointcut
我正在做一个包含登录和帐户的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
生效。我该如何解决这个问题?
由于您在 Spring基于引导的项目上工作,我建议您使用 Spring 安全功能或其他授权和身份验证框架,例如 Shiro。
如果您仍然希望使用其中的 none 个,您可以在超级 class 中使用 @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.
}
}
此外,根据我的经验,在 Spring 启动应用程序中直接使用 @Pointcut
是一种不好的做法。请改用 customized Spring annotation。
问题是您在切入点中定义了一个 JoinPoint
参数。它只属于使用切入点的建议方法,而不属于切入点本身。无论如何你都不会在那里使用它,因为永远不会执行切入点,该方法只是一个由 @Poinctut
注释装饰的虚拟对象。所以你想要的是:
@Pointcut("execution(* show.xianwu.game.frisbeescorer.controller.*.*(..))")
public void validateLogin() {
// check the login information
}
此外(与您的问题无关),.*.*
非常具体,仅匹配 class 中的方法,而该方法恰好位于包 show.xianwu.game.frisbeescorer.controller
中。如果您还想在子包中包含 classes,请改用 ..
语法,在本例中为 show.xianwu.game.frisbeescorer.controller..*
.
我正在做一个包含登录和帐户的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
生效。我该如何解决这个问题?
由于您在 Spring基于引导的项目上工作,我建议您使用 Spring 安全功能或其他授权和身份验证框架,例如 Shiro。
如果您仍然希望使用其中的 none 个,您可以在超级 class 中使用 @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.
}
}
此外,根据我的经验,在 Spring 启动应用程序中直接使用 @Pointcut
是一种不好的做法。请改用 customized Spring annotation。
问题是您在切入点中定义了一个 JoinPoint
参数。它只属于使用切入点的建议方法,而不属于切入点本身。无论如何你都不会在那里使用它,因为永远不会执行切入点,该方法只是一个由 @Poinctut
注释装饰的虚拟对象。所以你想要的是:
@Pointcut("execution(* show.xianwu.game.frisbeescorer.controller.*.*(..))")
public void validateLogin() {
// check the login information
}
此外(与您的问题无关),.*.*
非常具体,仅匹配 class 中的方法,而该方法恰好位于包 show.xianwu.game.frisbeescorer.controller
中。如果您还想在子包中包含 classes,请改用 ..
语法,在本例中为 show.xianwu.game.frisbeescorer.controller..*
.