我们在Dubbo中定义一个接口,这个接口采用上方说的 欺骗性
的命名方式,这个 getFeiChaoInfo()
中并没有返回值。
好了,然后我们将这个服务暴露,然后启动。按照肥朝之前的观念,命名不规范,无非是理解起来恶心了点,但是跑还是能跑的。结果一启动
之前看过肥朝Dubbo源码解析的同学,对这个服务暴露再熟悉不过了,根据异常栈,我们很快定位到了关键位置。
就算你连Dubbo都没用过也没关系,其实你从 javassist
和 CannotCompileException
这两个关键词就能猜到异常的原因。 javassist
常用于操作字节码, CannotCompileException
根据我小学三年级的英语都知道是无法编译异常。那为什么出现没办法编译通过呢?我们把这段Dubbo拼接出来,准备要用 javassist
进行编译的代码格式化一下就一目了然了
格式化后就很明显可以看出, getFeiChaoInfo()
这个方法没有返回值是编译不过去的。 那么这个时候有同学就想说了,Dubbo这段拼接代码进行编译的逻辑有bug啊。 鉴于公众号目前有小部分粉丝没用过Dubbo,我们先不讨论Dubbo为什么要这么做,我们反省一下自己,你这种欺骗性的方法名本身就有问题,再者,就算Dubbo把这个代码的容错性做好了又如何,你这种不规范的编码习惯,就算成功,也是 偶然成功!
,不信? 肥朝带你再看一个案发现场。
在项目中,我们经常会遇到DTO、BO、DO等转换的问题,很多同学用的是Apache或者Spring的BeanUtils来做copy,我们来一组性能测试
另外肥朝给大家总结了一条结论
凡是和反射相关的操作,基本都是低性能的。凡是和字节码相关的操作,基本都是高性能的。
由此可见,在各种POJO间转化,最高性能的肯定是直接操作get/set,但是这样写,肯定不够优雅。 从性能报告明显看出较优方案是使用cglib的 BeanCopiers
。 BeanCopiers
怎么使用这个自己搜索一下就知道了,那么我们再来看一起案发现场。 为了使用建造者模式,我们有同事这么做
好了。 然后跑一个简单的demo
看到有异常一些同学就慌了,就产生了这个东西虽然性能高,但是感觉好像不稳定的样子错觉。 其实并不是这东西不稳定,关键还是在于你会不会用。 再说了,世界每天都在变,除了肥朝会稳定给大家输出原创之外,还有什么是稳定的呢? 为此,肥朝给大家总结了以下几点使用上的常识
1.当源类和目标类的属性名称、类型都相同,拷贝结果棒棒哒。 2.当源对象和目标对象的属性名称相同、类型不同,那么名称相同而类型不同的属性不会被拷贝。另外注意,原始类型(int,short,char)和 他们的包装类型,在这里都被当成了不同类型。因此不会被拷贝。 3.源类或目标类的setter比getter少,拷贝没问题,此时setter多余,但是不会报错。 4.源类和目标类有相同的属性(两者的getter都存在),但是目标类的setter不存在,此时会抛出NullPointerException
关键是我们目标类 FeiChaoBO
的setter方法是存在的啊,那为什么还会出现这个异常? 很明显,正常的set方法都是 void
的。 然而这个案例中,set方法设置了返回值,存在一定的欺骗性。 而且就算要用建造者模式也不是这么用的,再退一万步说,建造者模式一般也是 build
命名而不是改set方法。
你再注意观察一下这两个案发现场,有没有发现一些共同的特点? javassist
和 cglib
,这两个框架最擅长的就是操作字节码,所以他们对 set
和 get
,都和如白纸版清纯的肥朝一样,非常的敏感! 所以建议老司机也不要随便乱动。
另外,据肥朝了解到,这个cglib的这个bug在 3.1
以后的版本是修复了的,但是 3.1
版本,目前使用的基数还是很大。
看过肥朝文章的粉丝都知道,肥朝反复强调要经过深度思考,开发中我们有无数的坑,不可能全部踩完的,关键是要经过一个坑,深度思考,提高编码意识! 因此,按照老套路,看看根据这次经验,我们试着再压榨出一些有效信息。
比如阿里开发手册提到了,getter和setter方法中,不要增加逻辑。 因为大家意识里面的getter和setter就是正常的获取属性,你如果加上了一定的逻辑,从一定程度上说,也存在欺骗性。
我们再继续压榨,布尔类型的get方法有些工具会生成isXXX,这个其实也是有坑的,当然也不排除你项目正在处于肥朝口中的 偶然成功
状态。
由此可见,取名是一个很大的学问,规范的命名是非常重要的,比如 肥朝
这么见名知意又时尚的名字,明显是经过深度思考得来的。有时候我真的很羡慕大家,每天都有这么多丰富多彩的故事,不像我,一个简简单单的“ 肥 ”字竟然就贯穿了一生!
更多源码原理实战,想与你分享。 扫描下方二维码,我们的故事就开始了。