pc|别再if-else走天下了,整个注解多优雅( 二 )
到此 , 似乎已经讲完了通过注解实现策略模式 , 干掉if-else的方法 , 就这样结束了吗?不 , 真正的重点从现在才开始 。
现在回过头看orderHandleMap这个Map , 它的key是订单来源 , 假如 , 我们想通过订单来源+订单支付方式这两个属性来决定到底使用哪一种OrderHandler怎么办?比如PC端支付宝支付的订单是一种处理逻辑(PCAliPayOrderHandler) , PC端微信支付的订单是另外一种处理逻辑(PCWeChatOrderHandler) , 对应的还有移动端支付宝支付(MobileAliPayOrderHandler)和移动端微信支付(MobileWeChatOrderHandler) 。
这时候我们的key应该存什么呢 , 可能有人会说 , 我直接存订单来源+订单支付方式组成的字符串不就行了吗?确实可以 , 但是如果这时业务逻辑又变了(向pm低头) , PC端支付宝支付和微信支付是同一种处理逻辑 , 而移动端支付宝支付和微信支付是不同的处理逻辑 , 那情况就变成了PCAliPayOrderHandler和PCWeChatOrderHandler这两个类是同一套代码逻辑 。 我们干掉了if-else , 但却造出了两份相同的代码 , 这是一个作为有强迫症的程序员所不能容忍的 。 怎么干掉这两个逻辑相同的类呢?
首先 , 我们可以回顾下 , 注解它究竟是个什么玩意?不知道大家有没有注意到定义注解的语法 , 也就是@interface , 与定义接口的语法想比 , 仅仅多了一个@ 。 翻看jdk , 可以找到这么一个接口Annotation , 如下
/** * The common interface extended by all annotation types. Note that an * interface that manually extends this one does not define * an annotation type. Also note that this interface does not itself * define an annotation type. * * More information about annotation types can be found in section 9.6 of * The Java Language Specification. * * The {@link java.lang.reflect.AnnotatedElement} interface discusses * compatibility concerns when evolving an annotation type from being * non-repeatable to being repeatable. * * @author Josh Bloch * @since 1.5 */public interface Annotation { // …省略}
开头就表明了 , The common interface extended by all annotation types 。 说的很明白了 , 其实注解它就是个接口 , 对 , 它就是个接口而已 , @interface仅仅是个语法糖 。 那么 , 注解既然是个接口 , 就必然会有相应的实现类 , 那实现类哪里来呢?上述中我们仅仅定义了OrderHandlerType注解 , 别的什么也没有做 。 这时候不得不提动态代理了 , 一定是jdk在背后为我们做了些什么 。 为了追踪JVM在运行过程中生成的JDK动态代理类 。 我们可以设置VM启动参数如下:
-Dsun.misc.ProxyGenerator.saveGeneratedFiles=true
该参数可以保存所生成的JDK动态代理类到本地 。 额外说一句 , 若我们想追踪cglib所生成的代理类 , 即对应的字节码文件 , 可以设置参数:
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "保存的路径")
添加参数后再次启动项目 , 可以看到我们项目里多了许多class文件(这里只截取了部分 , 笔者启动的项目共生成了97个动态代理类 。 由于我的项目是springboot环境 , 因此生成了许多如ConditionalOnMissingBean、Configuration、Autowired等注解对应的代理类):
【pc|别再if-else走天下了,整个注解多优雅】
本文插图
那接下来就是要找到我们所关心的 , 即jdk为我们自定义的OrderHandlerType注解所生成的代理类 。 由于jdk生成的动态代理类都会继承Proxy这个类 , 而java又是单继承的 , 所以 , 我们只需要找到实现了OrderHandlerType的类即可 。 遍历这些类文件 , 发现$Proxy63.class实现了我们定义的OrderHandlerType注解:
推荐阅读
- 北京日报|安全带插片网上热销 专家:别再花钱买“危险”
- 银行|有30万元存款,别再傻傻存定期了,银行行长:这样存年利过万
- 民生经济|原创 有30万元存款,别再傻傻存定期了,银行行长:这样存年利过万
- 经济|银行行长:手中有10万别再存定期,这样存一年利息近1万!
- 球鞋|央视点名曝光!这一行业涨的比房价还快,别再傻傻掉进“传销”
- [食物浪费 农产品 进出口 猪肉 蔬菜]|别再说吃不起猪肉,你每年浪费的猪肉量是进口量的2倍
- 球鞋|央视点名批评!这一行业已沦为下一个“传销”,别再傻傻“入套”
- |信用卡不为人知的4个“秘密”,小心被“吞钱”,别再多交钱了
- |DAO才是DeFi的最终形式?错过DeFi,千万别再错过DAO
- 民生经济|年轻人注意了,又一做法正在"掏空"你的钱包,别再傻傻买单
