0%

单例模式被序列化破坏的解决方案

饿汉模式-序列化

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
29
30
package tech.xixing.design.pattern.creational.singleton;

import java.io.Serializable;

/**
* @author xixing
* @version 1.0
* @date 2020/6/1 10:38
*/
public class HungrySingleton implements Serializable {
//private final static HungrySingleton hungrySingleton=new HungrySingleton();

private final static HungrySingleton hungrySingleton;
static {
hungrySingleton=new HungrySingleton();
}
private HungrySingleton(){

}

public static HungrySingleton getInstance(){
return hungrySingleton;
}

private Object readResolve(){
return hungrySingleton;
}


}

在最后加入方法readResolve()即可在反序列化中返回原来对象。

反射攻击预防

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
29
30
31
32
33
34
package tech.xixing.design.pattern.creational.singleton;

import java.io.Serializable;

/**
* @author xixing
* @version 1.0
* @date 2020/6/1 10:38
*/
public class HungrySingleton implements Serializable {
//private final static HungrySingleton hungrySingleton=new HungrySingleton();

private final static HungrySingleton hungrySingleton;
static {
hungrySingleton=new HungrySingleton();
}
//反射攻击预防
private HungrySingleton(){
if(hungrySingleton!=null){
throw new RuntimeException("单例模式禁止反射");
}

}

public static HungrySingleton getInstance(){
return hungrySingleton;
}

private Object readResolve(){
return hungrySingleton;
}


}

懒汉模式

对于懒汉模式,并不能对反射攻击进行有效防御

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
29
30
31
32
33
34
35
36
37
38
39
40
41
package tech.xixing.design.pattern.creational.singleton;

/**
* @author xixing
* @version 1.0
* @date 2020/6/1 8:45
*/
public class LazySingleton {
private static LazySingleton lazySingleton=null;

private static boolean flag=true;

private LazySingleton(){
if(!flag){
throw new RuntimeException("单例模式禁止反射");
}else {
flag=false;
}

}

/**
* 如果锁的是静态方法,相当于把这个class给锁了
* 锁的不是静态方法,相当于把堆内存中的实例锁了
* @return
*/
public synchronized static LazySingleton getInstance(){
if(lazySingleton==null){
lazySingleton=new LazySingleton();
}
return lazySingleton;
// synchronized (LazySingleton.class){
// if(lazySingleton==null){
// lazySingleton=new LazySingleton();
// }
// }
// return lazySingleton;
}


}
1
2
3
4
5
6
7
8
9
10
11
12
Class objectClass=LazySingleton.class;
LazySingleton lazySingleton = LazySingleton.getInstance();
Field flag=lazySingleton.getClass().getDeclaredField("flag");
flag.setAccessible(true);
flag.set(lazySingleton,true);
Constructor constructor=objectClass.getDeclaredConstructor();
constructor.setAccessible(true);
LazySingleton lazySingleton1 = (LazySingleton) constructor.newInstance();
//HungrySingleton hungrySingleton =(HungrySingleton) constructor.newInstance();
//HungrySingleton hungrySingleton1=HungrySingleton.getInstance();
System.out.println(lazySingleton);
System.out.println(lazySingleton1);