单例模式是在学习java之初就接触到的了,总结一下。
有些时候,允许自由创建某个类的实例没有意义,还可能造成系统性能下降(因为创建对象所带来的系统开销问题)。例如整个系统中只有一个窗口管理器,只有一个窗口管理器,只有一个窗口管理器,只有一个假脱机打印设备,在javaee应用中可能只需要一个数据库引擎访问点,Hibernate访问时只需要一个SessionFactory实例,如果在系统中为他们创建多个实例就没有太大的意义。
如果一个类始终只能创建一个实例,则这个类被称为单例类,这种模式就被称为单例模式。
对Spring框架而言,可以在配置Bean实例时指定scope=“singleton”来配置单例模式,不仅如此,如果配置<:bean./>元素时如果没有指定scope属性,则该实例默认就是单例的行为模式。
Spring推荐所有的业务组件,DAO组件,数据源等配置成单例的行为方式,因为这些组件无需保存任何用户状态,故所有的客户端都可以共享这些业务逻辑组件,DAO组件等,如果不借助Spring框架。我们也可以手动去实现单例模式,为了保证改类只能产生一个实例,程序不能允许自由创建该类的对象,因此我们需要使用private来修饰该类的构造函数,从而将其隐藏起来。
将构造器隐藏起来,需要一个public方法来作为访问该类调动访问点,用于创建该类的对象,且该方法必须使用static修饰(因为在调用方法前还不存在对象,因此调用该方法的不可能是对象,只能是类)。
除此之外,该类还必须缓存已经创建的对象,否则该类无法知道是否已经创建过实例,也就无法保证只创建了一个实例,为此该类需要使用一个静态属性来保存曾经创建的实例,且该属性需要被静态方法访问,所以属性也应该使用static修饰。
下面是一个单例类的实例:
public class Singleton(){
private Singleton(){};
private static Singleton instance;
public static Singleton getInstance(){
if(instance=null){
instance = new Singleton();
` }
return instance;
}
}
测试类:
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。