本文共 1434 字,大约阅读时间需要 4 分钟。
有些时候,允许自由创建某个类的实例没有意义,还可能造成系统性能下降(因为创建对象所带来的系统开销问题)。例如整个系统中只有一个窗口管理器,只有一个假脱机打印设备;在JavaEE应用中可能只需要一个数据库引擎访问点,Hibernate访问时只需要一个SessionFactory实例,如果在系统中为它们创建多个实例就没有太大的意义。
如果一个类始终只能创建一个实例,则这个类被成为单例类,这种模式就被称为单例模式。
对于Spring框架而言,可以在配置Bean实例时指定scope="singleton"来配置单例模式。不仅如此,如果配置<bean../>元素时如果没有指定scope属性,则该实例默认就是单例的行为方式。
Spring推荐将所有的业务组件,DAO组件,数据源等配置成单例的行为方式,因为这些组件无需保存任何用户状态,故所有客户端都可以共享这些业务逻辑组件、DAO组件等。如果不借助Spring框架,我们也可以手动实现单例模式。为了保证该类只能产生一个实例,程序不能允许自由创建该类的对象,因此我们需要使用private来修饰该类的构造器,从而将其隐藏起来。
将构造器隐藏起来后,需要提供一个public方法来作为访问该类的访问点,用于创建该类的对象,且该方法必须使用static修饰(因为在调用方法前还不存在对象,因此调用该方法的不可能是对象,只能是类)。
除此之外,该类还必须缓存已经创建的对象,否则该类无法知道是否曾经创建过实例,也就无法保证只创建了一个实例。为此该类需要使用一个静态属性来保存曾经创建的实例,且该属性需要被静态方法访问,所以属性也应该使用static修饰。
下面是一个单例类的实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Singleton { //使用这个对象来缓存已经创建的实例 private static Singleton singleton; //构造函数是private的,因此只能在本类中访问 private Singleton(){} //这个public方法来获取这个创建的实例 public static Singleton getInstance() { if (instance == null ) { singleton = new Singleton(); } return singleton; } } |
下面是测试类:
1 2 3 4 5 6 7 | public class Test { public static void main(String args[]) { Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1==s2); //将输出true } } |
在上面的Test类的代码中,只有通过Singleton的getInstance方法才可以获得Singleton的实例。在第一次调用时会在Singleton类中创建一个示例,第二次调用则返回这个已经创建的实例,以后每次调用也是。这就保证了Singleton实例只创建了一次。由于每次调用都返回的是同一个实例,因此,在Test中将输出true。
综上,一般的单例模式的类都具有以下特点:
私有构造器
私有静态类成员变量
公有获取该变量的方法
转载地址:http://wzdso.baihongyu.com/