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
42
43
44
45
package org.springframework.aop;
import java.io.Serializable;
/**
* Canonical Pointcut instance that always matches.
*
* @author Rod Johnson
*/
@SuppressWarnings("serial")
class TruePointcut implements Pointcut, Serializable {
public static final TruePointcut INSTANCE = new TruePointcut();
/**
* Enforce Singleton pattern.
*/
private TruePointcut() {
}
@Override
public ClassFilter getClassFilter() {
return ClassFilter.TRUE;
}
@Override
public MethodMatcher getMethodMatcher() {
return MethodMatcher.TRUE;
}
/**
* Required to support serialization. Replaces with canonical
* instance on deserialization, protecting Singleton pattern.
* Alternative to overriding {@code equals()}.
*/
private Object readResolve() {
return INSTANCE;
}
@Override
public String toString() {
return "Pointcut.TRUE";
}
}

这里直接给出TruePointcut的源码,可以看出其使用了单例模式。但是这里定义了一个private Object readResolve(),javadoc中还写着在反序列化时保护单例模式,那它是如何起到保护作用的呢?

联想到我们可以在序列化、反序列化时自定义writeObjectreadObject方法,那readResolve是不是与其类似呢?

1
2
3
4
5
private void writeObject(java.io.ObjectOutputStream s)
throws IOException;
private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException;

ObjectInputStream#readOrdinaryObject中的部分源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
if (desc.isExternalizable()) {
readExternalData((Externalizable) obj, desc);
} else {
readSerialData(obj, desc);
}
handles.finish(passHandle);
if (obj != null &&
handles.lookupException(passHandle) == null &&
desc.hasReadResolveMethod())
{
Object rep = desc.invokeReadResolve(obj);
if (unshared && rep.getClass().isArray()) {
rep = cloneArray(rep);
}
if (rep != obj) {
handles.setObject(passHandle, obj = rep);
}
}
return obj;
}

从源码可以看出,如果自定义了readResolve方法,反序列化的最终结果将取决于该方法的返回值。所以这里可以在反序列时保护单例模式