pc|别再if-else走天下了,整个注解多优雅( 三 )
public final class $Proxy63 extends Proxy implements OrderHandlerType { private static Method m1 private static Method m2 private static Method m4 private static Method m3 private static Method m0 public $Proxy63(InvocationHandler var1) throws { super(var1) } // …省略}
我们知道 , jdk动态代理其实现的核心是:
也就是这个构造函数的InvocationHandler对象了 。 那么注解的InvocationHandler是哪个具体实现呢?不难发现就是:
这个类里面的核心属性 , 就是那个 memberValues , 我们在使用注解时给注解属性的赋值 , 都存储在这个map里了 。 而代理类中的各种方法的实现 , 实际上是调用了 AnnotationInvocationHandler 里的 invoke 方法 。 好了 , 现在我们知道了注解就是个接口 , 且通过动态代理实现其中所定义的各种方法 。 那么回到我们的OrderService , 为什么不把key的类型设置为OrderHandlerType?就像这样 。
private Map
orderHandleMap
如此一来 , 不管决定订单处理器orderhandler的因素怎么变 , 我们便可以以不变应万变(这不就是我们所追求的代码高扩展性和灵活性么) 。 那当我们的map的key变成了OrderHandlerType之后 , 注入和获取的逻辑就要相应改变 , 注入的地方很好改变 , 如下:
public class OrderService { private Map
orderHandleMap @Autowired public void setOrderHandleMap(List { // 注入各种类型的订单处理类 orderHandleMap = orderHandlers.stream().collect( Collectors.toMap(orderHandler -> AnnotationUtils.findAnnotation(orderHandler.getClass(), OrderHandlerType.class), v -> v, (v1, v2) -> v1)) } // ...省略}
orderHandlers)
那获取的逻辑要怎么实现?我们怎么根据order的来源和支付方式去orderHandleMap里获取对应的OrderHandler呢?问题变成了如何关联order的来源和支付方式与OrderHandlerType注解 。 还记得刚才所说的注解就是个接口吗 , 既然是个接口 , 我们自己实现一个类不就完事了么 , 这样就把order的来源和支付方式与OrderHandlerType注解关联起来了 。 说干就干 , 现在我们有了这么一个类 ,
public class OrderHandlerTypeImpl implements OrderHandlerType { private String source private String payMethod OrderHandlerTypeImpl(String source, String payMethod) { this.source = source this.payMethod = payMethod } @Override public String source() { return source } @Override public String payMethod() { return payMethod } @Override public Class annotationType() { return OrderHandlerType.class } }
在获取对应OrderHandler时我们可以这样写 ,
public void orderService(Order order) { // ...一些前置处理 // 通过订单来源确以及支付方式获取对应的handler OrderHandlerType orderHandlerType = new OrderHandlerTypeImpl(order.getSource(), order.getPayMethod()) OrderHandler orderHandler = orderHandleMap.get(orderHandlerType) orderHandler.handle(order) // ...一些后置处理}
看起来没什么问题了 , 来运行一下 。 不对劲啊 , 空指针 , 那个异常它来了 。
我们断点打在NPE那一行 ,
本文插图
【来源:Java架构师之路】
声明:转载此文是出于传递更多信息之目的 。 若有来源标注错误或侵犯了您的合法权益 , 请作者持权属证明与本网联系 , 我们将及时更正、删除 , 谢谢 。邮箱地址:newmedia@xxcb.cn
推荐阅读
- 北京日报|安全带插片网上热销 专家:别再花钱买“危险”
- 银行|有30万元存款,别再傻傻存定期了,银行行长:这样存年利过万
- 民生经济|原创 有30万元存款,别再傻傻存定期了,银行行长:这样存年利过万
- 经济|银行行长:手中有10万别再存定期,这样存一年利息近1万!
- 球鞋|央视点名曝光!这一行业涨的比房价还快,别再傻傻掉进“传销”
- [食物浪费 农产品 进出口 猪肉 蔬菜]|别再说吃不起猪肉,你每年浪费的猪肉量是进口量的2倍
- 球鞋|央视点名批评!这一行业已沦为下一个“传销”,别再傻傻“入套”
- |信用卡不为人知的4个“秘密”,小心被“吞钱”,别再多交钱了
- |DAO才是DeFi的最终形式?错过DeFi,千万别再错过DAO
- 民生经济|年轻人注意了,又一做法正在"掏空"你的钱包,别再傻傻买单
