在Singlenton這種模式下,當一個服務第一次被請求的時候,這個服務的一個代理將會被生成。生成的這個代理實現了與實際服務相同的接口(也可以是對象),並且在服務接口的方法在第一次被調用的時候實際的服務對象(包括服務的實現類,攔截機,對別的服務的引用等)纔會真正被創建。
HiveMind內部通過SingletonServiceModel這個類來完成服務代理的生成和實際服務創建的工作。代理的生成主要利用了javassit包提供的代碼生成功能,動態的生成一個實現了所有服務接口方法的對象。
生成的代理(proxy)分爲內外兩層,以下稱外層代理爲_deferredProxy,內層代理爲_innerProxy。外層代理主要用於與用戶代碼交互或由其它服務引用,簡單點說就是用戶程序實際訪問的對象。內層的主要任務是當服務接口的某個方法第一次被訪問的時候生成實際的服務類並替換掉自己。在之後的調用將是通過外層代理直接調用實際服務類(如果服務接口定義的是一個實際類的話,還會爲這個類生成Bridge的一個包裝類),而不必經過內層代理的中轉。
比如有如下的接口和實現類:
public interface Person{
String getName();
}
public class Hawk{
String getName(){
return "Hawk";
}
}
在第一次請求服務之後會生成如下的兩個代理類:
//_deferredProxy
public class $Person_0 implements Person,RegistryShutdownListener{
private Person _inner;
private boolean _shutdown;
public final void registryDidShutdown(){
_shutdown = true;
}
public synchronized final void _setInner(Person inner){
_inner = inner;
}
private Person _getInner(){
if (_shutdown)
_inner = null;
throw org.apache.hivemind.HiveMind.createRegistryShutdownException();
return _inner;
}
//添加服務接口中的方法
public String getName(){
return (String)_getInner().getName();
}
}
//innerProxy
public class $Person_1 implements Person{
private $Person_0 _deferredProxy;
private Person _service;
private SingletonServiceModel _serviceModel;
pbulic $Person_1($Person_0 deferredProxy,SingletonServiceModel serviceModel){
_deferredProxy = deferredProxy;
_serviceModel = serviceModel;
_deferredProxy._setInner(this);
}
private synchronized final Person _service(){
if (_service == null)
_service = (Person))_serviceModel.getActualServiceImplementation();
//在這裏改變了外層代理的_inner屬性值,指向實際服務對象(或橋連對象)
_deferredProxy._setInner(_service);
return _service;
}
public final_instantiateServiceImplementation(){
_service();
}
//添加服務接口中的方法
public String getName(){
return (String)_service().getName();
}
通過上面的例子可以看到HiveMind是如何動態爲Singleton模式的服務類生成代理的,通過兩層代理間的方向調用完成了在第一次請求服務接口方法的時候生成實際對象。這種方法生成代理的好處是沒有動態調用,只在第一次請求或調用服務方法的時候需要額外的系統時間來生成代理類,其它時間都是直接調用。