Singleton Service Model in HiveMind

<script type="text/javascript"> document.location.href="http://blog.csdn.net/mindhawk/archive/2006/12/16/1444999.aspx"; </script>

    在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模式的服务类生成代理的,通过两层代理间的方向调用完成了在第一次请求服务接口方法的时候生成实际对象。这种方法生成代理的好处是没有动态调用,只在第一次请求或调用服务方法的时候需要额外的系统时间来生成代理类,其它时间都是直接调用。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用单例模式时,确保只有一个实例是非常重要的。如果有多个实例被创建,那么这将违反单例模式的规则,可能会导致应用程序中的错误行为。 在上面的示例中,SingletonService使用了一个静态变量instance来存储实例。在getInstance()方法中,如果instance为null,那么它将创建一个实例。因此,只有在第一次调用getInstance()方法时,才会创建实例。 为了验证SingletonService是否只创建了一个实例,可以在代码中添加一些日志来跟踪实例的数量。例如: ``` @Component public class SingletonService { private static int instanceCount = 0; private static SingletonService instance; private SingletonService() { instanceCount++; System.out.println("Creating instance #" + instanceCount); } public static synchronized SingletonService getInstance() { if (instance == null) { instance = new SingletonService(); } return instance; } public void doSomething() { System.out.println("Doing something..."); } } ``` 在上面的示例中,我们添加了一个静态计数器instanceCount,用于跟踪实例的数量。在SingletonService的构造函数中,我们打印了一条日志,以显示创建了多少个实例。 当我们在其他组件中调用SingletonService时,可以看到控制台输出,以查看SingletonService是否只创建了一个实例。例如: ``` @Service public class MyService { @Autowired private SingletonService singletonService; public void doSomething() { singletonService.doSomething(); } } // Output: // Creating instance #1 ``` 由于getInstance()方法只被调用一次,因此只创建了一个SingletonService实例。如果在应用程序的其他地方调用getInstance()方法,将不会创建新的实例,而是返回现有的实例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值