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 -&gt AnnotationUtils.findAnnotation(orderHandler.getClass(), OrderHandlerType.class), v -&gt v, (v1, v2) -&gt 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那一行 ,
pc|别再if-else走天下了,整个注解多优雅
本文插图
【来源:Java架构师之路】
声明:转载此文是出于传递更多信息之目的 。 若有来源标注错误或侵犯了您的合法权益 , 请作者持权属证明与本网联系 , 我们将及时更正、删除 , 谢谢 。邮箱地址:newmedia@xxcb.cn


推荐阅读