자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트(byte) 형태로 데이터를 변환하는 기술
JVM의 메모리에 상주(힙 or 스택)되어 있는 객체 데이터를 바이트 형태로 변환
직렬화된 데이터들은 파일 저장이나 네트워크 전송 시 파싱이 가능한 유의미한 데이터가 된다
잘 안쓰는 이유? 위험하고 까다롭다.
자바 시스템 간에만 사용할 수 있다.
역직렬화 시 클래스 구조 변경 문제
ex) 멤버 변수 타입 변경 → 예외 발생 → 역직렬화가 되지 않을 때와 같은 예외처리 필요
외부(DB, 캐시 서버, NoSQL 서버 등)에 장기간 저장될 정보는 자바 직렬화 사용 지양
개발자가 직접 컨트롤이 가능한 클래스(프레임워크 or 라이브러리)의 객체가 아닌 클래스의 객체에 대해서는 직렬화 지양
용량 문제
자바 직렬화시에 기본적으로 타입에 대한 정보 등 클래스의 메타 정보도 가지고 있기 때문에 상대적으로 다른 포맷에 비해서 용량이 큰 문제가 있습니다.
예를 들면 클래스 안에 클래스 또 리스트 등 이런 형태의 객체를 직렬화 하게 되면 내부에 참조하고 있는 모든 클래스에 대한 메타정보를 가지고 있기 때문에 용량이 비대해지게 됩니다. 그래서 JSON 같은 최소의 메타정보만 가지고 있으면 테스트로 된 포맷보다 같은 데이터에서 최소 2배 최대 10배 이상의 크기를 가질 수 있습니다.
스프링 프레임워크에서 기본적으로 지원하는 캐시 모듈 중 외부 시스템에 저장하는 형태에서 기본적으로 자바 직렬화 형태로 제공된다. (Spring Data Redis, Spring Session …)
새롭게 스타트하는 서비스 같은 경우에는 생산성을 위해서 자바 직렬화를 그대로 이용한다고 해도 트랙픽이 지속적으로 증가할 때에는 JSON 형태 또는 다른 형태의 직렬화로 바꿔주는 것 고려해보시길 바랍니다.
보안 - 보이지 않는 생성자 readObject
생성자에 있는 validation 로직이 적용되지 않는다. → 조작된 바이트 스트림에 대응 불가 → 커스텀 직렬화로 대응 가능(readObject메서드 정의)
싱글톤 문제 - 역직렬화 시 기본적으로 새로운 객체 생성
싱글톤 객체는 직렬화 하지 않는 것이 좋겠다..
언제 사용되는가
객체 상태를 영속해야 할 때(짧은 기간)
자바 시스템 간의 데이터 교환을 위해 사용
CSV, JSON, 프로토콜 버퍼 등은 시스템 고유 특성과 상관없는 대부분의 시스템에서의 데이터 교환 시 많이 사용된다.
자바에서도 CSV, JSON을 사용하면 되지 자바 직렬화를 써야 되는 이유?
JSON 또는 CSV 등 형태의 포맷을 이용하면 직렬화 또는 역직렬화시에 특정 라이브러리를 도입해야 쉽게 개발이 가능하면, 구조가 복잡하면 직접 매핑시켜줘야 하는 작업도 필요
복잡한 데이터 구조라도 직렬화 조건만 지키면 큰 작업 없이 바로 직렬화가 가능하다. 데이터 타입이 자동으로 맞춰지기 때문에 관련 부분에 큰 신경을 쓰지 않아도 된다.
활용 예시
서블릿 세션(Servlet Session)
세션을 파일로 저장하거나 세션 클러스터링, DB 저장
세션에 필요한 객체는 java.io.Serializable 인터페이스를 구현하는 것을 추천