-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
Description
Serializable 구현 문제
- Serializable을 구현하면 생성자 이외의 방법으로 인스턴스 생성 가능
- 버그와 보안문제
-> 직렬화 프록시 패턴
SerializableProxy 구현
public class Period implements Serializable {
private final Date start;
private final Date end;
public Period(Date start, Date end) {
this.start = new Date(start.getTime());
this.end = new Date(end.getTime());
if(this.start.compareTo(this.end) > 0) {
throw new IllegalArgumentException(start + "가 " + end + "보다 늦다.");
}
}
private static class SerializationProxy implements Serializable {
private final Date start;
private final Date end;
public SerializationProxy(Period p) {
this.start = p.start;
this.end = p.end;
}
}
}직렬화 프록시는 바깥 클래스와 완전히 같은 필드로 구성
Period.writeReplace
public class Period implements Serializable {
private Object writeReplace() {
return new SerializationProxy(this);
}
}직렬화시 호출
바깥 클래스(Period) 타입을 직렬화할 수 없음
Period.readObject
public class Period implements Serializable {
private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("프록시가 필요합니다.");
}
}역직렬화시 호출
Period를 직접 역직렬화할 수 없음
Period.SerializableProxy.readResolve
public class Period implements Serializable {
private static class SerializationProxy implements Serializable {
private Object readResolve() {
return new Period(start, end);
}
}
}직렬화 프록시를 통해서만 역직렬화 가능
생성자 혹은 정적 메서드를 통해서만 객체를 생성하므로 불변식이 깨질 위험이 낮음