Search code examples
javaspring-dataspring-aop

aspects are not working in my spring project


About Aspect class:

@Aspect
@Component
public class PostAop{

    @Around("execution(* com.blog.controllers.PostController.add(..)) && args(request,..)")
    public String Authorized(ProceedingJoinPoint jp, HttpServletRequest request) throws Throwable {

And for annotation 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;

}

And finaly this is my aspect configuration class:

@Configuration
@ComponentScan(basePackages = { "com.blog" })
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AspectConfig {
    @Bean
    public PostAop postAop(){
        return new PostAop();
    }
}

And this is 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";
    }

I actually don't know were is the probleme, I don't get any exception while running application but my aspect class PostAop never get called. Did i miss something in the configuration??


Solution

  • The pointcut expression

    @Around("execution(* com.blog.controllers.PostController.add(..)) && args(request,..)")
    

    can be explained as , advice a joinpoint (method execution in case of Spring AOP) which matches the following condition

    execution of a method com.blog.controllers.PostController.add of any return type (*) and any arguments (..)

    and

    that method should have HttpServletRequest request as its first argument

    Now in your PostController the method add(ModelMap model,Article article,HttpSession session) will not match the pointcut expression

    The pointcut expression would work if you remove the args(request,..) and you can access the HttpServletRequest as follows

    @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() is a scoping designator to narrow the scope of classes to advice.

    Note :

    When you annotate the Aspect class with @Component , it will be autodetected by the @ComponentScan(basePackages = { "com.blog" }) if the PostAop is placed at any level under the root package com.blog . This means you dont have to create the bean using factory method and @Bean annotation. Either one of @Component or @Bean is required.

    By java naming convention the name of the method will be authroized() and not Authorized()

    Hope this helps.