对软件系统来说升级就意味着风险,至少对数据和功能来说可能有不经意的破坏。尤其在电信系统中,通常要求严格的架构可用性和质量可靠边。增加一个新的功能经常充满困难的—就像其他如飞行模拟领域一样。 在这篇文章中,我会使用AOP来拦截我想要升级的方法。被拦截的代码就可以为操作系统提供过度的功能。对于下一个主版本(升级后的版本)来说,升级代码可以从被拦截的地方移到主版本代码中。在这里拦截的使用减少了升级主类的风险。 被拦截的代码是通过下面基于dynaop脚本文件来建立的(可参考dynaop project on java.net获取更多信息)。这个脚本文件注释一个类并为其在运行是被其他类拦截作准备。这并不是一个可执行脚本文件。 // Apply interceptor to all getter methods in the class NMSSubject.interceptor( NMSSubject.class, GET_METHODS, new UpgradeInterceptor()); NMSSubject类是一个Observer模式中的客户端;我们相要升级getNewData()方法。UpgradeInterceptor类提供了拦截getNewData()的AOP实现。一旦拦截成功,方法可以被参数化(调用JNDI命名服务)并且扩展的数据可以透明地返回给原来的客户端。 The Takeaway 我会使用Observer模式并且通过AOP升级一个子类方法。这里也显示了处理数据生成和使用的代码分离的意义。此外还顺便介绍一些软件架构的概念。 Observer模式 Observer模式(也称为发布-订阅)对设计包含一个服务器和多个客户端的类来说是非常有用的。他鼓励使用数据生成和使用分离的概念。一个来自网络管理的例子是一个服务器应用维护一个虚拟的设备网络拓朴图。他通过拉(主动请求)和(被动)听的组合来获取与设备和链接状态相关的消息。图1显示了一个服务器与一组网络设备通讯的方式。一组客户端通过Observer模式来得到服务器的数据。  Figure 1. Topology Server and the Observer Pattern 由服务器维护的图的真实度决定了用户对被管网络的了解。许多设备类型都支持自己的搜索方式;例如IP路由会尽力维护一份最新的周围网络图。如果一个远连接失败了,路由必须尽力计算出他对内部路由表的影响。这个过程称为收敛并且通常被认为是通用搜索问题的一个特例。更多与之相关的信息可以参考《网络管理,MIB和MPLS:原则,设计和实现》 回到图1,拓朴图可以用来与客户端通讯并且使用Observer模式保持最新。换句话说,当服务器检测到网络中的变更时他会使用Observer模式中相关方法与客户端通讯。 观察者主题 我的数据生成器(发布者)一个实现Subject接口的类NMSSubject。 你可以看到,Subject有三个方法允许加入/删除/通知观察者(通知是用来更新观察者的数据)。这些方法对NMSSubject的集合对象进行操作(NMS表示网络管理系统)。 public class NMSSubject implements Subject { Collection observers = new ArrayList(); public void addObserver(Observer observer) { observers.add(observer); } public void removeObserver(Observer observer) { this.observers.remove(observer); } public void notifyObservers() { for (Iterator i = observers.iterator(); i.hasNext();) ((Observer) i.next()).update(this); } // Have AOP intercept the next call and in turn call into JNDI // The legacy code might have been reading from a file or database. // The intercepted code could call into JNDI or some other API // This can be used as a temporary measure to avoid an upgrade public String getNewData() { return "Data Set: "; // Call into JNDI here via AOP }} NMSSubject中的最后一个方法是getNewData(),也是我们需要升级的代码。我们想通过AOP拦截getNewData()并且透明地升级他,那样客户端就不需要关心任何拦截了。 观察者客户端 一个简单接口提供了一个使用NMSSubject类作为参数的update方法。这个方法调用子类的getNewData()方法。 interface Observer { void update(NMSSubject subject); }public class NMSListener implements Observer {public void update(NMSSubject subject) { updateView(subject.getNewData()); }public void updateView(String data) { System.out.println("Updated subject data is " + data); }} getNewData()方法能过UpgradeInterceptor类来拦截升级。让我们看一下这个类。 通过AOP升级观察者监听器 一旦我们拦截了getNewData(),他返回的数据可以通过调用JNDI命名服务来参数化。这个调用搜索名为report.txt文件。文件中的数据被返回给调用者-- NMSListener.update()。 public class UpgradeInterceptor implements Interceptor{ public Object intercept(Invocation invocation) throws Throwable { String methodName = getFullMethodName(invocation); System.out.println("Intercepted method name: " + methodName); // Call the intercepted method. Object result = invocation.p[1] [2] 下一页
|
|