Serializable 인터페이스를 구현하겠다는 결정을 내리게 되면 버그나 보안 결함이 생길 가능성이 높다. 하지만 이런 위험을 크게 줄일 수 있는 기술이 하나 있다. 직렬화 프락시 패턴이라고 알려진 기법이다.
우선 바깥 클래스 객체의 논리적 상태를 간결하게 표현하는 직렬화 가능 클래스를 private static 중첩 클래스로 설계한다. 이 중첩클래스를 직렬화 프락시라고 부르는데, 바깥 클래스를 인자 자료형으로 사용하는 생성자를 하나만 가진다. 이 생성자는 인자에서 데이터를 복사하기만 한다. 일관성 검사를 할 필요도 없고, 방어적 복사를 할 필요도 없다.
아래는 Period 클래스의 프락시 코드이다.
이 메서드가 있으면 직렬화 시스템은 바깥 클래스 객체 대신 SerializationProxy 객체를 직렬화한ㄷ. 다시 말해서, writeReplace 메서드는 직렬화가 이루어지기 전에 바깥 클래스 객체를 직렬화 프락시 객체로 변환한다.
writeReplace 메서드를 갖추게 되면 직렬화 시스템은 바깥 클래스로 직렬화된 객체는 절대로 만들지 않는다. 하지만 공격자는 클르새의 불변식을 훼손하고자 그런 객체를 만들려 할 수도 있다. 그런 공격을 막으려면 아래의 readObject 메서드를 바깥 클래스에 추가해주면 된다.
마지막으로, SerializationProxy 클래스에 자기와 논리적으로 동일한 바깥 클래스 객체를 반환하는 readResolve 메서드를 추가해야 한다. 이 메서드가 있으면 직렬화 시스템은 역직렬화를 끝내자마자 직렬화 프락시 객체를 다시 바깥 클래스 객체로 변환하게 된다.
요약
'개발서적 > 이펙티브자바' 카테고리의 다른 글
[직렬화]규칙77. 개체 통제가 필요하다면 readResolve 대신 enum 자료형을 이용하라 (0) | 2017.05.10 |
---|---|
[직렬화]규칙76. readObject 메서드는 방어적으로 구현하라 (0) | 2017.05.10 |
[직렬화]규칙75. 사용자 지정 직렬화 형식을 사용하면 좋을지 따져 보라 (0) | 2017.05.09 |
[직렬화]규칙74. Serializable 인터페이스를 구현할 때는 신중하라 (0) | 2017.05.09 |
[병행성]규칙73. 스레드 그룹은 피하라 (0) | 2017.05.08 |