服务提供者框架是指这样一个系统:多个服务提供者实现一个服务,系统为服务提供者的客户端提供多个实现,并把他们从多个实现中解耦出来。
服务提供者框架有三个重要的组件:服务接口,这是提供者实现的;提供者注册API,这是系统用来注册实现,让客户端访问他们的;服务访问API,是客户端用来获取服务的实例的。服务访问API一般会提供一个默认实现的实例。服务访问API是灵活的静态工厂。它构成了服务提供者框架的基础。
还有一个组件是可选的:服务提供者接口,这些提供者负责创建其服务实现的实例。如果没有服务提供者,实现就用类名来注册,并通过反射方式进行实例化。
下面是一个简单的实现,包含一个服务提供者和默认的提供者和不包含提供者的例子。
/**
* @ClassName:Service
* @Description: service interface 多个服务提供者实现一个服务,系统为服务提供者的客户端提供多个实现
*/
public interface Service {
}
/**
*
* @ClassName:Provider
* @Description: service provider interface 服务提供者
*/
public interface Provider {
Service newService();
}
/**
* @ClassName:Services
* @Description: 有服务提供者接口模式
*/
public class Services {
private Services(){}
private static final Map<String ,Provider> providers = new ConcurrentHashMap<String ,Provider>();
private static final String DEFAULT_PROVIDER_NAME = "<def>";
public static void registerDefaultProvider(Provider p){
registerProvider(DEFAULT_PROVIDER_NAME,p);
}
public static void registerProvider(String name ,Provider p){
providers.put(name, p);
}
public static Service newInstance(){
return newInstance(DEFAULT_PROVIDER_NAME);
}
public static Service newInstance(String name){
Provider p = providers.get(name);
if(p==null)
throw new IllegalArgumentException("No provider registered with name" + name);
return p.newService();
}
}
/**
* @ClassName:Services
* @Description: 无服务提供者接口模式,注册类名
*/
public class Services{
private static final String DEFAULT_PROVIDER_CLASSNAME = "DefaultService";
private static final Map<String ,Class> providers = new ConcurrentHashMap<String ,Class>();
private static final String DEFAULT_PROVIDER_NAME = "<def>";
public static void registerProvider(String name ,String className){
try {
providers.put(name, Class.forName(className));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
static{
registerProvider(DEFAULT_PROVIDER_NAME,DEFAULT_PROVIDER_CLASSNAME);
}
public static Service newInstance(){
return newInstance(DEFAULT_PROVIDER_NAME);
}
public static Service newInstance(String name){
Class c = providers.get(name);
if(c==null)
return newInstance();
try {
return (Service)c.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}