면접을 준비하고 면접을 치는 과정에서 “Spring이란 무엇일까요?”라는 질문에 순간 당황을 했습니다. Spring Boot와의 차이점, 순수 Spring은 과연 우리에게 무엇을 지원하고 어떤 이유로 개발된 프레임워크인지 제대로 답할 수 없었기 때문입니다. 따라서 순수 Spring은 어떤 것이고 어떤 목적으로 제작되었는지 찾아보게 되었습니다.
Spring이 만들어지기 전에 EJB라는 자바 진영 표준 기술이 있었습니다. 이때 EJB는 굉장히 비싼 서버를 사용해야하며 또한 모든 코드가 EJB 인터페이스에 의존하여 개발된다는 문제가 있었습니다. 따라서 간단한 엔터프라이즈 애플리케이션을 만들더라도 EJB 인터페이스에 맞춰 복잡한 코드를 작성해야한다는 문제점이 있었습니다.
또한 기존의 간단한 비즈니스 로직을 원하는 시기에서 점점 복잡한 비즈니스 로직을 가진 애플리케이션을 요구하게 되었습니다. 하지만 이러한 것을 보장하기에 기존의 자바 코드는 비즈니스 로직이 복잡해지고 엔터프라이즈의 기술을 넣다보니 세부적인 동작을 파악하기 어려워지며 한 부분을 잘못 건들면 애플리케이션이 작동하지 않는 등의 문제가 발생하기 시작했습니다. 따라서 비즈니스 로직과 엔터프라이즈 애플리케이션에서 요구하는 안정성, 확장성, 보안등을 보장하는 애플리케이션을 제작하는 것은 굉장히 어려웠습니다.
위에서 말한 문제 중 2번째 문제는 EJB가 해결하려고 했습니다. 비즈니스 로직을 작성하는 과정에서 EJB가 기술적인 코드를 덜 작성하게 만들었으나 EJB의 규격에 종속되어야 하는 코드를 작성함에 있어서 이러한 문제는 제대로 해결되지 않았습니다. 또한 EJB의 규격에 맞추며 자바의 장점인 상속을 EJB 클래스를 상속하며 이러한 자바의 장점인 상속을 사용할 수 없게되고 따라서 다형성이라는 자바의 장점을 잃게 됩니다.
다양한 기술을 사용하며 또한 엔터프라이즈 애플리케이션 특성상 기술 및 환경이 바뀌는 경우 해당 기술 및 환경과 관련된 모든 코드를 수정해야 했습니다. 기존에는 모든 로직에서 해당 기술을 사용하는 모든 코드를 수정해야 하였습니다. 하지만 AOP를 통해 기술적인 코드가 중복되어 작성된 경우를 방지하여 만약 사용하는 기술이 바뀌는 경우 많은 코드를 수정할 필요를 없앴습니다. 또한 서비스의 추상화를 통해 외부 환경에 영향을 받지 않게 만들었습니다. 기술적인 복잡함을 캡슐화와 추상화를 통해 기술을 구현하는 부분과 기술을 사용하는 부분을 분리시켜 외부 환경의 영향을 받지 않게 하였습니다.
EJB에서 복잡하고 제한이 많은 기술에 질려버린 개발자들은 정말 간단한 클래스를 원하였습니다. 따라서 단순한 오브젝트라고 말하면 없어보여 설득력이 떨어진다고 생각하던 사람들은 POJO라는 용어를 만들며 자바의 단순한 오브젝트를 사용하여 애플리케이션 로직을 작성하는 것이 더 좋다고 생각하였습니다. 단순한 오브젝트를 사용하여 기존의 제한이 많고 복잡한 EJB를 이용한 개발보다 더 비즈니스 로직에 집중하게 되었습니다. 이러한 과정은 비즈니스 로직을 개발할때 발생할 수 있는 문제들을 줄여 비즈니스 로직에서의 오류를 줄이게 되었습니다.
평소 자바를 사용한다면 생성자를 사용하여 해당 클래스의 인스턴스를 만들어 직접 해당 인스턴스의 생성, 운용, 소멸의 과정을 직접 제어하는 것이 보통입니다. 하지만 Spring은 IoC를 통해 Spring 컨테이너가 우리가 만든 클래스들을 직접 제어하여 개발자는 그러한 생성 - 소멸의 과정을 신경쓰지 않고 비즈니스 로직에 집중하게 만들어줍니다. 비즈니스 로직이 아닌 외부 로직은 스프링에서 따로 처리를 맡아줍니다.
기존의 자바를 사용할 경우에는 인터페이스를 통해 추상화 작업을 거친 인스턴스를 사용하더라도 해당 인스턴스를 받는 과정에서 클래스에 의존하게 됩니다. 하지만 Spring 컨테이너에서 해당 인스턴스의 생성 - 소멸을 맡으며 기존의 자바 코드처럼 해당 클래스 소스코드 내부에서 해당 인스턴스를 생성하는 것이 아닌 스프링 컨테이너에서 해당 인스턴스를 생성하고 그 클래스에 해당 인스턴스를 주입해주게 됩니다. 이 과정에서 객체지향의 장점 중 추상화와 캡슐화를 얻어 해당 클래스를 개발하며 외부 클래스의 내부 동작이 어떻게 구성되는지는 알 필요가 없어졌습니다.
비즈니스 로직, 로깅, 트랜잭션 등 다양한 이유로 중복되는 코드가 작성됩니다. 중복되는 코드를 작성하는 번거로움과 유지보수에 알맞도록 AOP를 사용하여 중복되는 코드를 따로 빼둔 후 필요한 상황에 호출하여 사용합니다.
POJO는 기존의 EJB에서 사용하는 무겁고 복잡하며 특정 규격에 맞춰야하는 불편함을 해결하기 위해 비즈니스를 개발하는 클래스는 POJO 즉 간단한 오브젝트 상태여야 한다는 것입니다. 따라서 인터페이스, 상속을 의무적으로 해야하지 않고 비즈니스 로직에 집중할 수 있으며 비즈니스 로직에 따른 인터페이스, 상속을 사용할 수 있게 되어 자바의 장점을 극대화 할 수 있습니다.
정리를 간단하게 해보았으나 아직 어려운 내용도 많은 것 같습니다. 하지만 의존성 주입, 제어 반전의 경우에는 어느정도 알고 있던 스프링의 특징이였으나 AOP와 POJO의 경우 스프링의 특징인지 모르고 사용을 못하거나 자연스럽게 사용하는 것 같습니다. 지금은 전체적인 흐름만을 정리하였으나 차근차근 공부해보며 스프링의 특징과 장점을 알고 스프링 개발을 하는 과정에 있어 이러한 장점을 이용할 수 있는 개발자가 되기위해 더 노력해야할 것 같습니다.