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;
}
 

Technorati : Apache Discovery

jamax 2007-03-29 20:05 發表評論
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章