Threaded Service Model in HiveMind

    一般情況下,單例模式(singleton or primitive service models)足夠使用。在有些情況下,服務需要保留某些詳細狀態。狀態和多線程是沒有聯繫的,所以與線程綁定的服務模型在需要的時候會創建一個服務實例並把它綁定到當前線程中去。實例一但創建就會一直綁定在線程中直到現成消亡。一個服務實例唯一對應於綁定的線程並且只能從綁定線程中訪問。
    與服務幫定的服務模型使用一個在運行時生成的特殊的代理類支持這種行爲;這個代理是可以不同的線程中共享,但是當代理的方法被訪問的時候會將請求轉調到綁定在當前線程的內部服務實現中(這裏也是一個代理)。此時攔截器也以生成,攔截器實際調用將是一個實際服務的代理。
    在收到清除消息時服務實例將被拋棄;這是通過hivemind.ThreadEventNotifier服務控制的。如果你的程序中使用到了線程幫定的服務,你將負責調用服務的fireThreadCleanup()方法。
    一個核心實現最好實現Discardable接口,這樣,服務將在服務實例被拋棄時收到通知。
比如有如下的接口和實現類:
public interface Person{
    String getName();
}

public class Hawk{
    String getName(){
        return "Hawk";
    }
}

在第一次請求服務之後會生成如下的兩個代理類:
//內層代理
public class $Person_0 implements Person{
    private ThreadedServiceModel _serviceModel;
    private Person _service;
    public $Person_0(ThreadedServiceModel serviceModel){
        super();
        _serviceModel = serviceModel;
    }
    private final Person _service(){
      //返回綁定在當前線程中的服務實例,必要時會創建一個新的實例並綁定到當前線程。
       return (Person) _serviceModel.getServiceImplementationForCurrentThread()
    }
    //添加服務接口中的方法
    public String getName(){
        return (String)_service().getName();
    }
}
//外層代理
public class $Person_1 implements Person,RegistryShutdownListener{
    private boolean _shutdown;
    //如果有攔截器_delegate將會是攔截器的實例,攔截器調用纔是內層代理
    private $Person_0 _delegate;
    public $Person_1(Person delegate){
        super();
         _delegate = delegate;
    }
    public final void registryDidShutdown(){
        //如果_delegate實現了RegistryShutdownListener接口
        //_delegate.registryDidShutdown();
        _delegate = null;
        _shutdown = true;
    }
    private final $Person_0 _delegate(){
        if (_shutdown)
            throw org.apache.hivemind.HiveMind.createRegistryShutdownException();
        return _delegate;
    }
    //添加服務接口中的方法
    public String getName(){
        return (String)_delegate().getName();
    }
}
    通過上面的例子可以看到與線程綁定的服務模型和單例的服務模式一樣也是通過動態生成代碼實現的,同樣具有內外兩個代理類存在,但是它與單例模式的實現方法有了很大的不同。
    首先,它的外層代理在創建之後就不會有任何變化,不會想單例模式那樣用實際服務對象替換內層代理對象。
    其次,它的攔截器、內層代理和外層代理是同時創建的,對所有訪問對象是共享的。如果有攔截器的話外層代理調用的將會是攔截器,而攔截器調用的纔是內層代理。
    最後,調用服務的所有請求都將通過內層代理,內層代理再方向調用到構造它的ThreadedServiceModel去獲取與線程綁定的服務實例,直到此時具體服務實例纔會和當前線程關聯。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章