https://weicomes.tistory.com/63



[참고]



직렬화란?


직렬화를 왜 하냐고 물어본다면 다른 환경과 데이터를 주고 받으려면 동일한 데이터 구조를 가져야 하기 때문이다. 다른 환경이란 여러 주체들이 될 수 있다. 프로그램, 서버, 다른 컴퓨터, 핸드폰, TV 등 다양한 디바이스
제각기 다른 언어를 사용한다면 데이터 송신이 이루어질 수 없다.따라서, 파이썬만 직렬화를 하는 것이 아니다. C, Java, PHP, R 여러 언어들이 직렬화를 지원한다.

시리얼라이즈는 마치 줄줄이 소시지처럼 통일된 데이터를 전송가능한 형태로(데이터 스트림) 만드는 것이라고 생각하면 된다.


일련의 바이트로부터 데이터 구조를 추출하는 것이 반직렬화(deserialization)한다.

객체의 직렬화는  Object 또는 Data를  외부의 시스템에서도 사용할 수 있도록 바이트 단위로 변환하여 파일 또는 네트워크를 통해서 스트림(송수신)이 가능하도록 하는 것을 의미한다.


자바의 I/O 처리는, 정수, 문자열 바이트 단위의 처리만 지원했었다. 따라서 복잡한 내용을 저장/복원 하거나, 네트워크로 전송하기 위해서는 객체의 멤버변수의 각 내용을 일정한 형식으로 만들어(이것을 패킷이라고 한다) 전송해야 했다.


객체직렬화는 객체의 내용(구체적으로는 멤버변수의 내용)을 자바 I/O가 자동적으로 바이트 단위로 변환하여, 저장/복원하거나 네트워크로 전송할 수 있도록 기능을 제공해준다. 즉 개발자 입장에서는 객체가 아무리 복잡하더라도, 객체직렬화를 이용하면 객체의 내용을 자바 I/O가 자동으로 바이트 단위로 변환하여 저장이나 전송을 해주게 된다. 


자바에서 직렬화는 자동으로 처리해주는 것이기 때문에, 운영체제가 달라도 전혀 문제되지 않는다. 객체를 직렬화할때 객체의 맴버변수가 다른 객체(Serializable 인터페이스를 구현한)의 레퍼런스 변수인 경우에는 레퍼런스 변수가 가리키는 해당 객체까지도 같이 객체직렬화를 해버린다.


또 그 객체가 다른 객체를 다시 가리키고 있다면, 같은 식으로 색체 직렬화가 계속해서 일어나게 된다. 이것은 마치 객체직렬화를 처음 시작한 객체를 중심으로 트리 구조의 객체직렬화가 연속적으로 일어나는 것이다. 




직렬화의 장점


객체 내용을 입출력형식에 구애받지 않고 객체를 파일에 저장함으로써 영속성을 제공한다.

객체를 네트워크를 통해 손쉽게 교환할 수 있다.




객체 전송의 단계 


객체를 분해하여 전송하기 위해서는 직렬화(Serialization) 되어야 한다.


객체를 전송하기 위해서는 3가지 단계를 거친다.


(1) 직렬화된 객체를 바이트 단위로 분해한다. (marshalling)

(2) 직렬화 되어 분해된 데이터를 순서에 따라 전송한다.

(3) 전송 받은 데이터를 원래대로 복구한다. (unmarshalling) 



Marshalling


- 마샬링(Marshalling)은 데이터를 바이트의 덩어리로 만들어 스트림에 보낼 수 있는 형태로 바꾸는 변환 작업을 뜻한다. 


- 자바에서 마샬링을 적용할 수 있는 데이터는 원시 자료형과 객체 중에서 Serializable 인터페이스를 구현한 클래스로 만들어진 객체이다.


- 객체는 원시 자료형과 달리 일정한 크기를 가지지 않고 객체 내부의 멤버 변수가 다르기 때문에 크기가 천차만별로 달라진다. 이런 문제점을 처리할 수 있는게 ObjectOutputStream 클래스이다. 




직렬화 


- 마샬링으로 바이트로 분해된 객체는 스트림을 통해 전송될 준비가 되었다. 앞에서 언급한대로 객체를 마샬링하기 위해서는 Serializable 인터페이스를 구현한 클래스로 만들어진 객체에 한해서만 마샬링이 진행될 수 있다.

Serializable 인터페이스는 아무런 메소드가 없고 단순히 자바 버추얼 머신에게 정보를 전달하는 의미만을 가진다.


*직렬화가 가능한 객체의 조건

(1) 기본형 타입(boolean, char, … )은 직렬화가 가능

(2) Serializable 인터페이스를 구현한 객체여야 한다.

(3) 해당 객체의 멤버들 중에 Serializable 인터페이스가 구현되지 않은 객체가 존재해서는 안된다.

(4) transient가 사용된 멤버는 전송되지 않는다. (보안 변수 : null 전송)



Unmarshalling


언마샬링은 객체 스트림을 통해서 전달된 바이트 덩어리를 원래의 객체로 복구하는 작업이다. 이 작업을 제대로 수행하기 위해서는 반드시 어떤 객체 형태로 복구할지 형 변환을 정확하게 해주어야 한다. 




SerialVersionUID, 클래스의 버전관리


직렬화하면 내부에서 자동으로 SerialVersionUID라는 고유의 번호를 생성하여 관리한다. 이 UID는 직렬화와 역직렬화 할 때 중요한 역할을 한다. 이 값이 맞는지 확인 후 처리하기 때문이다. 만약 이 SerialVersionUID 값이 맞지 않는다면 오류를 출력한다.


객체 생성 당시의 UID와 현재 변경한 이후의 UID는 내부에서 자동으로 생성되어 관리되므로 UID가 달라 오류가 발생할 수 있다. 이러한 문제로 Java에서는 SerialVersionUID를 직접 선언하고 관리하는 방식을 적극 권장하고 있다. 


+ Recent posts