Skip to content

Effective Java ‐ Item 90⚠️

dnwls16071 edited this page Aug 16, 2025 · 1 revision

아이템 90 - 직렬화된 인스턴스 대신 직렬화 프록시 사용을 검토하라.

  • 여태까지 공부한 내용을 토대로 봤을 때, Serializable 인터페이스를 구현하기로 결정한 순간 언어의 정상 메커니즘인 생성자 이외의 방법으로 인스턴스를 생성할 수 있게 된다.
  • 결국 버그와 보안 문제로 이어질 가능성이 매우 커진다.
  • 이런 위험을 크게 줄여줄 기법으로 바로 직렬화 프록시 패턴(Serialization Proxy Pattern)이 있다.
public final class Period implements Serializable {
  
    private final Date start;
    private final Date end;
  
    public Period(Date start, Date end) {
        if (this.start.compareTo(this.end) > 0) {
            throw new IllegalArgumentException(start + "가 " + end + "보다 늦다.");
        }
        this.start = new Date(start.getTime());
        this.end = new Date(end.getTime());
    }
  
    private Object writeReplace() {
        return new SerializationProxy(this);
    }
  
    private void readObject(ObjectInputStream stream) throws InvalidObjectException {
        throw new InvalidObjectException("프록시가 필요합니다");
    }
  
    //바깥 클래스의 논리적 상태를 정밀하게 표현하는 중첩 클래스(Period의 직렬화 프록시)
    private static class SerializationProxy implements Serializable {
  
        private static final long serialVersionUID = 234098243823485285L;
  
        private final Date start;
        private final Date end;
  
        SerializationProxy(Period p) {
            this.start = p.start;
            this.end = p.end;
        }
  
        private Object readResolve() {
            return new Period(start, end);
        }
    }
}
  • 가짜 바이트 스트림 공격과 내부 필드 탈취 공격을 프록시 수준에서 차단해준다.
  • 필드들을 final로 선언해도 되므로 Period 클래스를 진정한 불변으로 만들 수 있다.
  • 역직렬화때 유효성 검사를 하지 않아도 된다.
  • 역직렬화한 인스턴스와 원래의 직렬화된 인스턴스의 클래스가 달라도 정상 작동한다.

직렬화 프록시 패턴의 한계

  • 클라이언트가 멋대로 확장할 수 있는 클래스에는 적용할 수 없다.
  • 객체그래프 순환이 있는 클래스에는 적용할 수 없다.
  • 방어적 복사보다 느리다.

확장할 수 없는 클래스라면 가능한 직렬화 프록시 패턴을 사용하자.

📖 Java

📖 Kotlin

📖 Coroutine

📖 Spring

📖 Spring Security

📖 Spring Batch

📖 Reactive Programming

📖 Database

📖 MySQL

📖 Redis

📖 JPA

📖 QueryDsl

📖 MSA

📖 Kafka

📖 Apache Flink

  • [Apache Flink - Apache Flink Architecture]
  • [Apache Flink - Stream Processing]
  • [Apache Flink - Data Stream API & Window]
  • [Apache Flink - State Management]

📖 HTTP

📖 AWS

📖 Docker

📖 Kubernetes

📖 CI/CD

📖 Nginx

📖 Monitoring🥈

  • [Monitoring - Log Concept]
  • [Monitoring - Log Level & Filter]
  • [Monitoring - Logback]
  • [Monitoring - Log Collection with ELK Stack]
  • [Monitoring - Log Monitoring with Kibana]
  • [Monitoring - Building a Monitoring System with Spring Boot Actuator]
  • [Monitoring - Server Monitoring with Prometheus and Grafana with Discord Alerts]

📖 Test

📖 Effective Java 3/E

📖 Kotlin Academy - Effective Kotlin

📖 Kotlin Academy - 핵심편

📖 스프링으로 시작하는 리액티브 프로그래밍

📖 가상 면접 사례로 배우는 대규모 시스템 설계 기초 1

📖 가상 면접 사례로 배우는 대규모 시스템 설계 기초 2

📖 Clean Code

📖 리팩토링 2판

📖 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식

📖 GraphQL

Clone this wiki locally