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