직렬화와 마샬링
매번 마샬링과 직렬화 키워드를 볼 때마다, 느낌으로만 알고 있었다. 그러나 이펙티브 자바 아이템 3 에서 이 개념에 대해 나왔기 때문에 이번기회에 제대로 정리하고 가려고 한다.
직렬화와 마샬링의 공통점
이 둘의 공통점은 객체를 직렬화 한다는 점이다. 직렬화는 객체를 다른 곳으로 전송하거나, 저장하기 위해서 사용된다.
직렬화와 마샬링은 거의 비슷하게 사용된다. 위에 사진과 같이 마샬링이 직렬화보다 더 큰 범위를 가지며, 직렬화는 마샬링의 한 부분이다.
직렬화(Serialization)
직렬화란?
직렬화는 객체의 필드를 바이너리 형식이나 바이트스트림으로 바꾸는 작업을 말한다. 굳이 바이트스트림이 아니여도 파일이나, 메모리, 데이터베이스 등으로 바꾸는 작업도 포함된다. 여기서 중요한 점은 직렬화 되는 대상은 객체의 값이나, 컨텐츠라는 점이며, 클래스 정의는 포함되지 않는다. 그러므로 메소드 같은 정보는 직렬화 되지 않는다.
바이트스트림(Byte Stream)
스트림은 데이터 배열이다. Input stream은 데이터를 읽으며 output stream은 데이터를 쓰는 작업을 한다. 자바 바이트 스트림은 한번에 8비트(1바이트)를 사용하여 input과 output을 처리한다. 바이트 스트림은 바이너리 파일같은 로우 데이터를 처리하는데 알맞다. 또 자바 캐릭터 스트림이 있는데, 이 스트림은 한글자는 2바이트 취급을 하므로, 한번에 2바이트씩 처리한다. 캐릭터 스트림은 text 파일을 처리할 때 유용하다.
역직렬화란?
직렬화의 반대로, 바이트스트림을 객체로 다시 되돌리는 것이다.
언제 직렬화를 사용할까?
JVM의 생명주기를 넘어서 객체를 유지시키고 싶을 때 사용한다.
ATM을 예를 들어보자. 만약 내가 ATM을 이용해 은행서버에서 돈을 인출했다고 가정하자. 그러면 인출계좌정보를 서버에게 던져주고, 서버는 인출계좌정보를 다시 역직렬화 해서 해당되는 로직을 태운다.
또한 SpringBoot의 기본 직렬화인 MappingJacskon2MessageConvert 는 직렬화도 지원하고 마샬링도 지원하는 듯 하다.
자바에서 직렬화를 어떻게 구현할까?
-
java.io.Serializable
인터페이스를 구현한다. -
java.io.ObjectOutputStream
클래스를 사용하여 객체를 영속화 한다.writeObject(<<instance>>)
: 객체를 직렬화 할 때 쓰는 메소드readObject()
: 객체를 역직렬화 할 때 쓰는 메소드
마샬링(Marshalling)
마샬링이란?
마샬링은 직렬화와 거의 비슷한데 다른점은 코드베이스를 포함하여 객체를 직렬화 한다.
🤔 코드베이스?
코드베이스는 객체를 받는이에게 이 객체의 구현을 어디서 찾을 수 있는지에 관한 정보를 말한다. 만약 다른 프로그램에게 객체를 전달했는데 이 객체를 다시 사용하려면 데이터 타입에 관한 정보가 있어야 한다. 코드베이스는 이 데이터가 어디에 있는지 알려주는 정보를 말한다.
코드베이스가 있기 때문에, 객체의 정보를 알지 못하는 다른 JVM에게 마샬링을 통해서 건네주면, 그 JVM이 언마샬링을 통해, 객체를 원래 상태로 되돌릴 수 있다. 이런 장점을 통해 RMI 같은 기능을 사용할 수 도 있다.
RMI(Remote Method Invocation)
RIM을 사용하면 자바에 분산 애플리케이션 메카니즘 API를 제공할 수 있다. RMI은 객체가 다른 JVM에서 실행중인 객체에서 메서드를 호출할 수 있습니다.
정리
직렬화와 마샬링은 매우 비슷하며, 코드베이스를 갖고 있냐 없냐의 차이다. 또한 Redis 같은 경우도 직렬화를 사용한다고 하니 배달의 민족 자바 직렬화 편 을 보시면 도움이 될 것 같다.