在Controller类中使用自定义注释时,自动装配不起作用

时间:2019-02-01 16:52:53

标签: java spring spring-mvc spring-aop

我尝试为日志记录方法执行时间创建自定义注释,直到我在控制器类中未使用的方法上使用注释之前,它都可以正常工作。在控制器类中使用时,其他类(服务类)的自动装配失败,并给出Null Pointer异常。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
}

-

@Aspect
@Component
public class ExampleAspect {

    @Around("@annotation(LogExecutionTime)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();

        Object proceed = joinPoint.proceed();

        long executionTime = System.currentTimeMillis() - start;

        System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");
        return proceed;
    }

}

当我在Controller以外的任何类上使用此注释时,它工作正常。

@RestController
public class ProjectController {

    @Autowired
    ProjectService projectService;

    @GetMapping("/testTimeTaken")
    @LogExecutionTime
    private String testTimeTaken() {
        return projectService.dummyMethod();
    }

}

1 个答案:

答案 0 :(得分:0)

您不能使用方面来“捕获”私有方法。

摘自Spring参考资料:

由于Spring的AOP框架基于代理的性质,根据定义,无论是JDK代理(在不适用的情况下)还是CGLIB代理(在技术上可行,但不是这样),都不会拦截受保护的方法推荐用于AOP)。结果,任何给定的切入点将仅与公共方法匹配! 如果您的拦截需求包括受保护的/私有方法甚至构造函数,请考虑使用Spring驱动的本机AspectJ编织,而不是Spring的基于代理的AOP框架。这构成了具有不同特性的AOP使用模式的不同,因此请确保在做出决定之前先熟悉编织。

所以最好的办法是将方法设为公开->私有String testTimeTaken()