[Spring] Serializable?

nathan·2022년 3월 16일
2

Spring

목록 보기
3/4

Serializable?

  • 문제 : Spring으로 로그인을 구현(Contoller 계층에서)하던 중 session에 User 객체를 setAttribute 해주려고 했더니, 이런 문구로 밑줄이 떴다.

    Non-serializable objects should not be stored in "HttpSession" objects

우선 직렬화란 무엇인가

  • 자바의 정석 책에 따르면, 직렬화(serialization)란 객체를 데이터 스트림으로 만드는 것을 뜻한다. 다시 얘기하면 객체에 저장된 데이터를 스트림에 쓰기(write)위해 연속적인(serial) 데이터로 변환하는 것을 말한다.
  • 반대의 과정은 역직렬화(deserialization)라고 한다.
  • 단순히 말하면, 자바 시스템 내부에서 사용되는 Object 또는 Data를 외부의 자바 시스템에서도 사용할 수 있도록 byte 형태로 데이터를 변환하는 기술이다.

왜 사용되는가

  • CSV, JSON, 프로토콜 버퍼 등은 시스템 고유 특성과 상관 없는 대부분의 시스템에서의 데이터 교환에 많이 사용한다.
  • 그러나 자바 직렬화 형태의 데이터 교환은 자바 시스템 간의 데이터 교환을 위해서 존재한다.

그럼 자바에서도 CSV, JSON을 사용해서 데이터 교환을 하면 되는 것 아닌가?

  • 굳이 자바 직렬화를 써야하는 데에 의문을 품을 수 있다.
  • 결론은, 목적에 따라 적절히 써야한다.고 한다.
    • 직렬화는 자바 시스템에서 개발에 최적화 되어있다.
    • 복잡한 데이터 구조의 클래스 객체도, 직렬화 기본 조건만 지켜졌다면, 큰 작업 없이 직렬화가 가능하다.(역직렬화도 마찬가지) 따라서, 데이터 타입이 자동으로 맞춰지는 등의 혜택(?)을 누릴 수 있다.

언제 사용되는가

  • JVM의 메모리에서만 상주되어있는 객체 데이터를 그대로 영속화(Persistence)가 필요할 때 사용한다고 한다.

어디에 사용되는가

  • 서블릿 세션(Servlet Session)

    • 서블릿 기반의 WAS(톰캣, 웹로직 등)들은 대부분 세션의 자바 직렬화를 지원한다.
    • 세션을 서블릿 메모리 위에서 운용할 땐, 직렬화를 필요로하지 않는다. 아마 외부의 자바 시스템에서 사용하는 것이 아니기 때문일 것으로 생각한다.
    • 그러나 세션을 파일로 저장하거나 세션 클러스터링, DB를 저장하는 옵션 등을 선택할 때는 세션 자체가 직렬화가 되어 전달된다고 한다.
      • 따라서 세션에 필요한 객체는 java.io.Serializable 인터페이스를 implements 해두는 것이 좋을듯하다.
    • 위 내용은 서블릿 스펙에서는 직접 기술한 내용이 아니므로, 구현한 WAS마다 동작이 달라질 수 있음을 염두에 두자.
  • 캐시(Cache)

    • 자바 시스템에서 퍼포먼스를 위하여 캐시 라이브러리(Ehcache, Redis, Memcached)를 많이 이용한다고 한다.
    • 자바로 시스템을 개발할 때 클래스가 자연스레 많아질 수 밖에 없다.
    • 예를 들어, DB 조회 이후 가져온 데이터 객체를 실시간으로 요구하는 상황이 아니라면, 메모리, 외부 저장소, 파일 등을 저장소를 이용하여 데이터 객체를 저장해서, 동일 요청이 오면, DB가 아닌 저장된 객체를 찾아 응답하게 되는 형태를 보통 캐시를 사용한다. 라고 한다.
    • 캐시 이용시, DB에 대한 리소스를 절약할 수 있어 많은 시스템에서 자주 활용된다.
    • 이렇게 캐시할 부분을 자바 직렬화된 데이터를 저장해서 사용한다. (물론 자바 직렬화만 사용해서 캐시를 저장하는건 아님 but 가장 간편하기 때문에 많이 사용됨)

이로 인해 드는 생각

  • 그렇다면, 로그인 시에 세션을 사용하게 되는데,
    이 때 유저 객체에 대한 정보를 DB에서 가져오게 되고,
    이를 통하여 로그인 한 사용자가 자기 자신임을 확인하는 작업이 필요할 때, 세션과 쿠키가 이용된다.

  • 이 때, 서블릿은 세션의 자바 직렬화를 지원한다.

  • 그리고, 서블릿 메모리 위에서 세션을 운용할 때는 굳이 직렬화가 필요하지 않다.

  • 따라서 결론적으로는 굳이 Seriarizable을 implements 할 필요는 없었다.

  • 허나 IntelliJ에서 알려줬던 이유는, 세션에서 이용될 객체이므로 직렬화를 해둬라. 라는 의미로 이해할 수 있겠다.


Reference

profile
나는 날마다 모든 면에서 점점 더 나아지고 있다.

0개의 댓글