Apache Commons Discovery 与面向服务编程
使用Apache Commons 的 Discovery 工具包可以实现接口和实现的分离,包括JAR SPI规范的简单实现。结合面向接口的编程方法,可以实现一个简单的面向服务的调用方式。
//初始化
ClassLoaders loaders =
ClassLoaders.getAppLoaders(serviceClass, serviceClass.getClass(), false);
DiscoverClass discover = new DiscoverClass(loaders);
// 使用newInstance方式直接产生接口实现的实例
implInstance = (PublicService) discover.newInstance(serviceClass, defaultImpl);
// 也可以使用find的方式返回对应的实现类
implClass = discover.find(serviceClass, configFile, defaultImpl);
上面的用法中,接口和实现类的映射关系在一个properties配置文件中定义,格式是:
XXXable=XXXimpl
也可以在classpath中的jar的META-INF/services中定义,格式是:
META-INF/services/xxxable(文件) 文件内容为 xxximpl
以下事完整程序中使用了cglib的 net.sf.cglib.proxy.Enhancer 对返回的实现类进行了增强,可以实现一个简单的面向方面的程序结构:
public class ServiceFinder { private static final String configFile = "services.properties"; private static Enhancer enhancer = new Enhancer(); private ServiceFinder() { } public static PublicService lookup(Class serviceClass) { return lookup(serviceClass, null); } public static PublicService lookup(Class serviceClass, String defaultImpl) { // 创建一个类装入器的实例 ClassLoaders loaders = ClassLoaders.getAppLoaders(serviceClass, serviceClass.getClass(), false); DiscoverClass discover = new DiscoverClass(loaders); PublicService impl = null; try { Class implClass = null; // 用DiscoverClass的实例来查找实现类 if (defaultImpl == null || "".equals(defaultImpl)) { implClass = discover.find(serviceClass, PropertiyFile.load(configFile)); } else { implClass = discover.find(serviceClass, configFile, defaultImpl); } enhancer.setSuperclass(implClass); enhancer.setCallback(new ServiceInterceptor(implClass.toString())); impl = (PublicService) enhancer.create(); // using DiscoverClass instance lookup the impelement //impl = (PublicService) discover.newInstance(serviceClass, defaultImpl); } catch (Exception ex) { ex.printStackTrace(); throw new IllegalArgumentException("无法获取指定的服务项"); } return impl; }
上一篇: SOA学习笔记 SOA设计模式项目管理搜索引擎ActiveMQ
下一篇: 关于页面框架的详细介绍