我是AOP的新手,目前正尝试为使用自定义注释注释的控制器方法实现一个方面。 当调用 myFunction 时,我总是在存储库上获得 NullPointerException 。似乎我有两个控制器实例。其中一个是在没有自动装配存储库的情况下实例化的。当我删除@MyAnnotation时,一切都按预期工作。
你能否告诉我如何强制Spring / AspectJ使用我的构造函数?
我的控制器如下:
@RestController
@RequestMapping(value = "/api")
public class MyController {
private Repository repository;
public MyController(Repository repository) {
this.repository = repository;
}
@RequestMapping(value = "/{variable1}", method = GET)
@MyAnnotation
public final FeatureCollection myFunction(
final @PathVariable(required = true) long variable1
) {
repository.findById(variable1);
(...)
}
}
方面:
@Aspect
public class MyAspect {
@Around("@annotation(MyAnnotation)")
public Object any(ProceedingJoinPoint pjp) throws Throwable {
return pjp.proceed();
}
}
配置:
@Configuration
@EnableAspectJAutoProxy
public class WebConfig {
@Bean
public MyAspect myAspect() {
return new MyAspect();
}
}
答案 0 :(得分:1)
尝试使用@Autowired
注释构造函数@Autowired
public MyController(Repository repository) {
this.repository = repository;
}
答案 1 :(得分:0)
这是因为带注释的方法是final
。
如果您可以删除final
关键字,那么它就可以使用。
如果你谷歌类似于"弹出最后的方法",你会发现更多信息,但基本上,当Spring创建代理时,它会从你的原始类生成一个子类,以包装用你的方面打电话给超级。问题是子类不能继承最终方法,因此代理很难工作。因此,很多限制来自于此,而AOP对final
的东西并没有那么多。
在文档中提到了这个限制,我不认为你会得到一个解决方法:
11.6代理机制
...
final
方法无法建议,因为它们无法被覆盖。
希望这会对你有帮助!