使用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