spring 与设计模式(创建型)之单例Singleton

一、前言

Singleton 模式主要作用是保证Java程序中,一个类Class只有一个实例存在,例如在数据中连接,全局计数器。另外Singleton也有能够无状态化,提供工具的性质功能。

二、两种形式

1、

public class Singleton {

  private Singleton(){}

  //在自己内部定义自己一个实例,是不是很奇怪?
  //注意这是private 只供内部调用

  private static Singleton instance = new Singleton();

  //这里提供了一个供外部访问本class的静态方法,可以直接访问  
  public static Singleton getInstance() {
    return instance;   
   } 
} 

 

2

public class Singleton { 

  private static Singleton instance = null;

  public static synchronized Singleton getInstance() {

  //这个方法比上面有所改进,不用每次都进行生成对象,只是第一次     
  //使用时生成实例,提高了效率!
  if (instance==null)
    instance=new Singleton();
  return instance;   } 

} 

 
 

三、在spring 中的应用 

问题如下:如果一个singleton的Bean依赖于一个prototype的Bean,如何让这个singleton的Bean每次获得最新的prototype类型的Bean?

 当Spring容器中作用域不同的Bean相互依赖时,可能出现一些问题,例如:一个作用域为Singleton的Bean(设为A)依赖于一个作用域为prototype的Bean(设为B)。由于A是单例的,只有一次初始化的机会,它的依赖关系也只在初始化阶段被设置,但它所依赖的B每次都会创建一个全新的实例,这将使A中的B不能及时得到更新。这样将导致如果客户端多次请求A,并调用A中B的某个方法(或获取A中B的某个属性),服务端总是返回同一个B,但客户端直接请求B却能获得最新的对象,这就产生了对象不同步的情况。这样就违背了B初衷:本来希望B具有prototype的行为,但是却表现出singleton的行为了。那么,问题如何解决呢?

    办法有二:

  • 部分放弃依赖注入:当A每次需要B时,主动向容器请求新的Bean实例,即可保证每次注入的B都是最新的实例。

  • 利用方法注入。

    第一种方式显然不是一个好的做法,代码主动请求Bean实例,必然导致代码与SpringAPI耦合在一起,造成严重的代码污染。通常情况下,我们会采用第二种做法。使用方法注入。

    方法注入通常使用lookup方法注入,利用lookup方法注入可以让Spring容器重写容器中Bean的抽象或具体方法,返回查找容器中其他Bean的结果,被查找的Bean通常是一个non-singleton的Bean(尽管也可以是一个singleton的Bean)。Spring通过使用CGLIB库修改客户端的二进制码,从而实现上述要求。看下面的例子:

?
1
2
3
4
5
6
7
8
public  class  CellPhone  implements  Phone {
     public  CellPhone() {
         System.out.println( "Spring实例化依赖的Bean...CellPhone实例" );
     }
     public  return  call() {
         return  "正在打电话..." ;
     }
}

    上面的CellPhone将被部署成prototype的Bean,并被一个singleton的Bean所依赖。如果让Spring容器直接将prototype的Bean注入到singleton中,就会出现上面的问题。为了解决这个问题࿰

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值