方面在我的 spring 项目中不起作用
aspects are not working in my spring project
关于看点class:
@Aspect
@Component
public class PostAop{
@Around("execution(* com.blog.controllers.PostController.add(..)) && args(request,..)")
public String Authorized(ProceedingJoinPoint jp, HttpServletRequest request) throws Throwable {
以及注释class:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // can use in method only.
public @interface Authorized {
public boolean Admin() default true;
public boolean Writer() default false;
}
最后这是我的方面配置 class:
@Configuration
@ComponentScan(basePackages = { "com.blog" })
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AspectConfig {
@Bean
public PostAop postAop(){
return new PostAop();
}
}
这是 PostController class:
@Controller
@RequestMapping(value = {"","/post"})
public class PostController {
...
@GetMapping("/add")
@Authorized(Writer = true)
public String add(ModelMap model,Article article,HttpSession session) {
model.addAttribute("tags", tagService.getAllTags());
model.addAttribute("users", userService.getAllUsers());
model.addAttribute("post", post);
return "post/add";
}
我实际上不知道是什么问题,我在 运行 应用程序时没有得到任何异常,但我的方面 class PostAop 从未被调用。我是不是遗漏了什么配置??
切入点表达式
@Around("execution(* com.blog.controllers.PostController.add(..)) && args(request,..)")
可以解释为,建议一个符合以下条件的连接点(Spring AOP 的方法执行)
执行任何 return 类型 (*) 和任何参数 (..) 的方法 com.blog.controllers.PostController.add
和
该方法应将 HttpServletRequest request
作为其第一个参数
现在在您的 PostController
中,方法 add(ModelMap model,Article article,HttpSession session)
将不匹配切入点表达式
如果删除 args(request,..)
切入点表达式将起作用,并且您可以按如下方式访问 HttpServletRequest
@Around("execution(* com.blog.controllers.PostController.add(..)) && within(com.blog.controllers..*)")
public String authorized(ProceedingJoinPoint jp) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
return (String) jp.proceed();
}
within()
是一个范围指示符,用于将 classes 的范围缩小为建议。
注:
当您使用 @Component
注释 Aspect
class 时,如果 PostAop
被放置在下面的任何级别,@ComponentScan(basePackages = { "com.blog" })
将自动检测到根包 com.blog
。这意味着您不必使用工厂方法和 @Bean
注释创建 bean。需要 @Component
或 @Bean
之一。
根据 java 命名约定,方法的名称将是 authroized()
而不是 Authorized()
希望对您有所帮助。
关于看点class:
@Aspect
@Component
public class PostAop{
@Around("execution(* com.blog.controllers.PostController.add(..)) && args(request,..)")
public String Authorized(ProceedingJoinPoint jp, HttpServletRequest request) throws Throwable {
以及注释class:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // can use in method only.
public @interface Authorized {
public boolean Admin() default true;
public boolean Writer() default false;
}
最后这是我的方面配置 class:
@Configuration
@ComponentScan(basePackages = { "com.blog" })
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AspectConfig {
@Bean
public PostAop postAop(){
return new PostAop();
}
}
这是 PostController class:
@Controller
@RequestMapping(value = {"","/post"})
public class PostController {
...
@GetMapping("/add")
@Authorized(Writer = true)
public String add(ModelMap model,Article article,HttpSession session) {
model.addAttribute("tags", tagService.getAllTags());
model.addAttribute("users", userService.getAllUsers());
model.addAttribute("post", post);
return "post/add";
}
我实际上不知道是什么问题,我在 运行 应用程序时没有得到任何异常,但我的方面 class PostAop 从未被调用。我是不是遗漏了什么配置??
切入点表达式
@Around("execution(* com.blog.controllers.PostController.add(..)) && args(request,..)")
可以解释为,建议一个符合以下条件的连接点(Spring AOP 的方法执行)
执行任何 return 类型 (*) 和任何参数 (..) 的方法 com.blog.controllers.PostController.add
和
该方法应将 HttpServletRequest request
作为其第一个参数
现在在您的 PostController
中,方法 add(ModelMap model,Article article,HttpSession session)
将不匹配切入点表达式
如果删除 args(request,..)
切入点表达式将起作用,并且您可以按如下方式访问 HttpServletRequest
@Around("execution(* com.blog.controllers.PostController.add(..)) && within(com.blog.controllers..*)")
public String authorized(ProceedingJoinPoint jp) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
return (String) jp.proceed();
}
within()
是一个范围指示符,用于将 classes 的范围缩小为建议。
注:
当您使用 @Component
注释 Aspect
class 时,如果 PostAop
被放置在下面的任何级别,@ComponentScan(basePackages = { "com.blog" })
将自动检测到根包 com.blog
。这意味着您不必使用工厂方法和 @Bean
注释创建 bean。需要 @Component
或 @Bean
之一。
根据 java 命名约定,方法的名称将是 authroized()
而不是 Authorized()
希望对您有所帮助。