这是我参与更文挑战的第4天,活动详情查看: 更文挑战
本文正在参加「Java主题月 – Java 开发实战」,详情查看 活动链接
开场白不多说,继续来聊聊Spring中的设计模式
单例模式
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这里插一点题外话,创建型模式又是什么?
24种设计模式可以总结为三大类模式,分别是:创建型模式、结构型模式、行为型模式
创建型模式 :顾名思义,就是用来创建对象的模式。它抽象了实例化过程,帮助一个系统独立于如何创建、组合和表示它的对象。
包含了
- 工厂模式(Factory Pattern)
- 抽象工厂模式(Abstract Factory Pattern)
- 单例模式(Singleton Pattern)
- 建造者模式(Builder Pattern)
- 原型模式(Prototype Pattern)
Spring Boot设计的九种设计模式中,简单工厂模式、抽象工厂模式都属于工厂模式,也是一种创建型模式
好了,回到主题单例模式上
怎样判断是否为单例模式?
- 一个类有且只有一个实例。
- 一个私有的构造器
- 一个私有的该类类型的变量必须有一个共有的返回类型为该类类型的方法,用来返回这个唯一的变量
单利模式
public class SingletonPatternDemo {
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
if(s1==s2)
System.out.println("该类是单例模式");
else
System.out.println("该类不是单例模式");
}
}
//定义一个类
class Singleton{
private Singleton(){} //private 只能在自己内部供自己去访问
private static Singleton instance=new Singleton();//在自己内部定义自己的一个实例
public static Singleton getInstance(){ //此静态方法供外部直接访问
return instance;
}
}
复制代码
** 非单例模式**
class Singleton{
private Singleton(){}
private static Singleton instance;
public static Singleton getInstance(){
return instance = new Singleton(); //每次getInstance方法被调用都会new一个新的对象
}
}
复制代码
单例模式的实现方式:
懒汉式
“懒汉式”主要是调用到这个实例的时候,才来判断是否存在,没有则创建一个新的实例,这与上面非单例模式的一种情况很类似,“懒汉式”严格说不算于单例模式,不过这点不纠结
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance()
//public static synchronized Singleton getInstance() //要保证线程安全,加上“synchronized ”关键字
{
if (instance == null) {
instance = new Singleton(); shi
}
return instance;
}
}
复制代码
饿汉模式
“饿汉式”指先把实例初始化,调用的时候直接反馈该实例即可,缺点是初始化后有可能不被调用,这样就浪费了初始化的资源
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
复制代码
单例模式的实现方式还有两种:
双检锁/双重校验锁(DCL,即 double-checked locking)
1.增加 “volatile”关键字
2. getSingleton方法内部两次判空校验
第一个if减少性能开销,第二个if避免生成多个对象实例。
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
复制代码
除了以上的实现方式,还有静态内部类、枚举等方式
在Spring中
Spring依赖注入Bean实例默认是单例的。
Spring的依赖注入(包括lazy-init方式)都是发生在AbstractBeanFactory的getBean里。getBean的doGetBean方法调用getSingleton进行bean的创建
今日小结:目前对单例模式的使用有了初步的理解,但对于它在Spring IOC中的应用还需深入理解