<script type="text/javascript"> document.location.href="http://blog.csdn.net/mindhawk/archive/2006/12/16/1444995.aspx"; </script> 一般情况下,单例模式(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去获取与线程绑定的服务实例,直到此时具体服务实例才会和当前线程关联。
与服务帮定的服务模型使用一个在运行时生成的特殊的代理类支持这种行为;这个代理是可以不同的线程中共享,但是当代理的方法被访问的时候会将请求转调到绑定在当前线程的内部服务实现中(这里也是一个代理)。此时拦截器也以生成,拦截器实际调用将是一个实际服务的代理。
在收到清除消息时服务实例将被抛弃;这是通过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去获取与线程绑定的服务实例,直到此时具体服务实例才会和当前线程关联。