也就是 4 行代码,其实应该是 2 行核心代码,就完成了让 @Async 支持表达式的这个需求。
而且官方是先给你说了解决方案是什么,只要你稍微你跟进一下,发动你的小脑壳思考一下,我想你写出这 4 行代码也不是什么困难的事情。
这就是给 Spring 贡献源码了,而且是一个比较有价值的贡献。如果是你抓住了这个机会,你完全可以在简历上写一句:给 Spring 贡献过源码,让 @Async 注解支持表达式的配置方式。
一般来说对 Spring 了解不深入的朋友,看到这句话的时候,只会觉得很牛逼,想着应该是个大佬。
但是实际上,2 行核心代码就搞定了。
所以你说给 Spring 贡献源码这个事儿难吗?
机会总是有的,就看你有没有上心了。
什么,你问我有没有给 Spring 贡献过源码?
我没有,我就是不上心,咋的了。
这是我写这个文章想要表达的第个观点:
给开源项目贡献源码其实不是一件特别困难的事情,不要老想着一次就提交一整个功能上去。一点点改进,都是好的。
调试技巧
前面提到的代码改进, Spring 还没有发布官方的包,但是我想要自己试验一下,怎么办呢?
你当然可以把 Spring 的源码拉下来,然后自己编译一波,最后本地改改源码试一试。
但是这个过程太过复杂了,基本上可以说是一个劝退的流程。
为了这么一个小验证,完全不值当。
所以我教你一个我自己研究出来的“骚”操作。
首先,我本地的 Spring 版本是 5.3.16,对应这部分的源码是这样的:
这个时候我们可以看到 qualifier 还是一个表达式的形式。
接着骚操作就来了。
你点击这个图标,对应的快捷键是 Alt+F8:
那么,如果我把这次提交的这 4 行代码,利用 Evaluate Expression 功能执行一下,是不是就算是模拟了对应的修改后的功能了?
我就问你:这个方法“骚”不“骚”。
接下来,我们就实操起来。
把这几行代码,填入到 Evaluate 里面:
if (beanFactory instanceof ConfigurableBeanFactory) { EmbeddedValueResolver embeddedValueResolver = new EmbeddedValueResolver((ConfigurableBeanFactory)beanFactory); qualifier = embeddedValueResolver.resolveStringValue(qualifier); }
输入代码片段,记得点击一下这个图标:
说明我的“偷梁换柱”大法成功了。
这不比你去编译一份 Spring 源代码来的方便的多?
而且这个调试的方法,相当于是你在 debug 的时候还能再额外执行一些代码,所以有的时候真的有时候能起到奇效。
这是我写这篇文章的第二个目的,想要分享给你这个调试方法。
不同之处
细心的读者肯定发现了,官方的代码有点奇怪啊:
我们常用的写法都是标号为 ① 那样的,当我在我的环境里面写出标号为 ② 的代码的时候,ide 给我了一个提示:
Patterns in 'instanceof' are not supported at language level '8'
大概意思是说 instanceof 的这个用法在 JDK 8 里面是不支持的。
看到这个提示的一瞬间,我突然想起了,这个写法好像是 JDK 某个高级版本之后支持的,很久之前在某个地方瞟到过一眼。
然后我用 “Patterns instanceof” 关键词查了一下,发现果然是 JDK 14 版本之后支持的一个新特性。
我就直接把文章中的例子拿出来给你说一下。
我们用 instanceof 的时候,基本上都是需要检查对象的类型的场景,不同的类型对应不同的逻辑。
好,我问你,你使用 instanceof,在类型匹配上了之后,你的下一步操作是什么?
是不是对对象进行强制类型转换?
比如这样的:
在上述代码截图中,我们每种情况要通过 instanceof 判断 animal 的具体类型,然后强制类型转换声明为局部变量,接着根据具体的类型执行指定的函数。
这有的写法有很多缺点:
- 这么写非常单调乏味,需要检测类型然后强制类型转换。
- 每个 if 都要出现三次类型名。
- 类型转换和变量声明可读性很差
- 重复声明类型名意味着很容易出错,可能导致未预料到的运行时错误。
- 每新增一个animal 类型就要修改这里的函数。
注意我加粗的地方,和原文是一样的,这波强调和细节是拉满了的: