|
使用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;
}
<!---->Technorati: Apache Discovery
http://www.blogjava.net/ideame/aggbug/107319.html
jamax2007-03-29 20:05 发表评论 |
|