拿这个代码去套“Closest”这个玩意。
首先,cause 就是抛出的 TimeoutException。
而 methods 这个 Map 里面装的就是三个被 @Recover 注解修饰的方法。
为什么有三个?
好问题,说明我前面写的很烂,导致你看的不太明白。没事,我再给你看看往 methods 里面 put 东西的部分的代码:
这三个方法都满足被 @Recover 注解的条件,且同时也满足返回值和目标方法 callChannel 的返回值一致的条件。那就都得往 methods 里面 put,所以是三个。
这里也解释了为什么兜底方法是用一个 Map 装着呢?
我最开始觉得这是“兜底方法”的兜底策略,因为永远要把用户当做那啥,你不知道它会写出什么神奇的代码。
比如我上面的例子,其实最后生效的一定是这个方法:
@Recover public void channelNotResp(TimeoutException timeoutException) throws Exception { log.info("3.没有获取到渠道的返回信息,发送预警!"); }
因为它是 Closest。
给你截个图,表示我没有乱说:
但是,校稿的时候我发现这个地方不对,并不是用户那啥,而是真的有可能会出现一个 @Retryable 修饰的方法,针对不同的异常有不同的兜底方法的。
比如下面这样:
当 num=1 的时候,触发的是超时兜底策略,日志是这样的:
http://localhost:8080/callChannel?num=1
妙啊,真的是妙不可言啊。
看到这里我觉得对于 Spring-retry 这个组件算是入门了,有了一个基本的掌握,对于主干流程是摸的个七七八八,简历上可以用“掌握”了。
后续只需要把大的枝干处和细节处都摸一摸,就可以把“掌握”修改为“熟悉”了。
有点瑕疵
最后,再补充一个有点瑕疵的东西。
再看一下它处理 @Recover 的方法这里,只是对方法的返回值进行了处理:
我当时看到这里的第一眼的时候就觉不对劲,少了对一种情况的判断,那就是:泛型。
比如我搞个这玩意:
按理来说我希望的兜底策略是 channelNotRespInt 方法。
但是执行之后你就会发现,是有一定几率选到 channelNotRespStr 方法的:
假设我们要支持泛型呢?
从 github 上的描述来看,目前作者已经开始着力于这个方法的研究了:
从 1.3.2 版本之后会支持泛型的。
但是目前 maven 仓库里面最高的版本还是在 1.3.1:
想看代码怎么办?
只有把源码拉下来看一眼了。
直接看这个类的提交记录:
org.springframework.retry.annotation.RecoverAnnotationRecoveryHandler
可以看到判断条件发生了变化,增加了对于泛型的处理。
我这里就是指个路,你要是有兴趣去研究就把源码拉下来看一下。具体是怎么实现的我就不写了,写的太长了也没人看,先留个坑在这里吧。