Item 90 : 직렬화된 인스턴스 대신 직렬화 프록시 사용을 검토하라
2021. 9. 27. 20:11
- Serializable을 구현하기로 결정한 순간 언어의 정상 메커니즘인 생성자 이외의 방법으로 인스턴스를 생성할 수 있게 된다.
- 직렬화 프록시 패턴을 사용하면 보안과 버그의 위협을 줄일 수 있다.
직렬화 프록시, serialization proxy pattern
- 바깥 클래스의 논리적 상태를 정밀하게 표현하는 중첩 클래스를 설계해 private static으로 선언
- 여기서 중첩 클래스가 바깥 클래스의 직렬화 프록시이다.
- 중첩 클래스의 생성자는 단 하나여야하고 바깥 클래스를 매개변수로 받아야 함
- 이 생성자는 단순히 인수로 넘어온 인스턴스의 데이터를 복사함
// Period 클래스용 직렬화 프록시
private static class SerializationProxy implements Serializable {
private final Date start;
private final Date end;
SerializationProxy(Period p) {
this.start = start;
this.end = end;
}
private static final long serialVersionUID =
23409824382341829L; // 아무 값이나 상관 없음
}
// 바깥 클래스에 writePlace 메소드 추가
// 직렬화 프록시 패턴용 writeReplace 메소드
private Object writeReplace() {
return new SerializationProxy(this);
}
/* 이 메소드가 바깥 클래스 인스턴스 대신
* SerilizationProxy의 인스턴스를 반환하는 역할을 함
/
- writePlace 덕분에 직렬화 시스템은 결코 바깥 클래스의 직렬화된 인스턴스를 생성할 수 없음
- readObject 메소드를 다음과 같이 설계해 공격도 방어할 수 있다
private void readObject(ObjectInputStream stream)
throws InvalidObjectException {
throws new InvalidObjectException("프록시가 필요합니다.");
}
- readResolve 메소드는공개된 API만을 사용해 바깥 클래스의 인스턴스를 생성한다.
직렬화 프록시의 한계
- 클라이언트가 멋대로 확장할 수 있는 클래스에는 적용할 수 없다.
- 객체 그래프에 순환이 있는 클래스에도 적용할 수 없다.
- 직렬화 프록시 패턴이 주는 강력함과 안전성에도 대가는 따르다 - 속도가 느려진다.
'책 > 이펙티브자바' 카테고리의 다른 글
이펙티브 자바 리뷰 (1회독을 마치며) (0) | 2021.09.28 |
---|---|
Item 89 : 인스턴스 수를 통제해야 한다면 readResolve 보다는 열거 타입을 사용하라 (0) | 2021.09.26 |
Item 88 : readObject 메소드는 방어적으로 작성하라 (0) | 2021.09.25 |
Item 87 : 커스텀 직렬화 형태를 고려해보라 (0) | 2021.09.24 |
Item 86 : Serializable을 구현할지는 신중히 결정하라 (0) | 2021.09.23 |