茂展的分享博客

单例模式漏洞

单例模式的漏洞

我们实现单例模式可以有5种实现方式,分别是 懒汉式、饿汉式、双重锁模式、枚举模式、静态内部类模式,但是呢,由于双重锁和JMM结构不一致吗,一般不推荐使用,但是其他的除了枚举模式以外,其他的都可被攻破

反射攻击模式

1
2
3
4
5
6
7
//1.通过反射攻破单例模式
Class<SingletonDemo2> clazz = (Class<SingletonDemo2>) Class.forName("com.nyist.singleton.SingletonDemo2");
Constructor constructor = clazz.getDeclaredConstructor(null);
constructor.setAccessible(true);
SingletonDemo2 singletonDemo21 = clazz.newInstance();
SingletonDemo2 singletonDemo22 = clazz.newInstance();
System.out.println(singletonDemo21 == singletonDemo22);

最后打印出的结果是false。也就是创建了不同的对象,即打破了单例模式。
那么如何补救呢,可以这样,构建方法内判断对象存在后再决定是否创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class SingletonDemo1 {

private static SingletonDemo1 demo1 = new SingletonDemo1(); //类初始化的时候,立刻加载对象

private SingletonDemo1() {
if(demo1 == null){
demo1 = new SingletonDemo1();
}
}

public static SingletonDemo1 getInstance(){
return demo1;
}
}

序列化反序列化方式

我们可以结合对象字节流的操作,将字节流先存储在文件中,然后读取,会创建一个不一样的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//2.通过序列化攻破单例模式
FileOutputStream fileOutputStream = null;
ObjectOutputStream objectOutputStream = null;
ObjectInputStream objectInputStream = null;
FileInputStream fileInputStream = null;
try {
SingletonDemo2 singletonDemo2 = SingletonDemo2.getInstance();
System.out.println("开始");
System.out.println(singletonDemo2);
fileOutputStream = new FileOutputStream("D:/test.txt");
objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(singletonDemo2);

fileInputStream = new FileInputStream("D:/test.txt");
objectInputStream = new ObjectInputStream(fileInputStream);
SingletonDemo2 demo2 = (SingletonDemo2) objectInputStream.readObject();
System.out.println("结束");
System.out.println(demo2);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
fileInputStream.close();
objectInputStream.close();
objectOutputStream.close();
fileOutputStream.close();
}

结果demo2和singletonDemo2的地址不相同,表示没有遵守单例模式
我们如何避免呢
在相应的类中加上此方法即可
解决单例模式反序列化攻破
以后学习中,继续总结,走起…

------本文结束感谢阅读------
🐶 您的支持将鼓励我继续创作 🐶