spring注解旁路问题讨论
下面是样例测试代码:
@Componentstatic class Downloader {@Autowired@LazyDownloader self;private int counter = 0;@FuncTracepublic void download() {log.info("Downloader.download");try {this.preProcess();self.downloadInternal("1.txt");log.info("download success");} catch (Exception e) {log.info("download catch error");}}@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 1000L, multiplier = 1.5))@FuncTracepublic void downloadInternal(String filePath) {counter++;log.info("downloadInternal times:" + counter);throw new Exception("download failed");}@FuncTracepublic void preProcess() {log.info("pre processing...");}}
@FuncTrace是用@Aspect做的打印函数进出日志的注解。@Retryable是spring自带的重试注解。
加了这两个注解后的函数,要使得注解生效,需用自注入的self方式调用,否则调用的还是原始的逻辑,而非切面动态编织(weave)后的逻辑。换言之,this调用的是函数在编译期的字节码,self调用的则是函数被动态代理后的新字节码。在需要self调用的场合使用了this调用,就会导致注解旁路。
另外,@Aspect切面只能处理public、protected、package访问权限的成员函数,像private、static成员函数均无法拦截,所以,private或static成员函数上的注解是没有意义的。