-
Spring Framework가 탄생하게 된 배경Spring&SpringBoot 2025. 2. 3. 09:28
Spring 프레임워크 등장 배경을 간단히 서술한 문서입니다.
Spring Framework가 나오기 전에는 앤터프라이즈 애플리케이션 개발에 EJB(Enterprise JavaBeans)라는 프레임워크가 있었습니다.
그러나 EJB에는 복잡성과 높은 결합도, 무거운 컨테이너, 느린 초기화, 유연성 부족, 테스트의 어려움 등의 문제가 있었습니다.
복잡성과 높은 결합도 EJB 에는 클래스(*컴포넌트라 부릅니다. 이 뒤로는 전부 컴포넌트라 표현하겠습니다.) 간 의존성이 매우 강하게 결합돼 있었습니다.
클래스 A가 클래스 B에 의존한다면 B 객체를 먼저 생성해야하는 순서에 제약이 생깁니다.
EJB를 사용할 때는 개발자가 JNDI(Java Naming and Directory Interface)를 이용해 수동으로 의존성을 해결해야 했습니다.
무거운 컨테이너EJB의 컨테이너는 객체(*Spring에서는 빈이라고 표현합니다.)뿐만 아니라 트랜잭션, 보안, 네트워크 연결, 스레드 관리 같은 부가적인 기능까지 전부 맡고 있었습니다.
단순 객체 관리를 넘어 무거운 기능까지 모두 컨트롤했고, 컨테이너는 무거워졌으며, 리소스를 많이 쓰고, 초기화가 느리고, 특정 서버에 종속적인 형태가 되어버렸습니다.느린 초기화* EJB는 애플리케이션이 시작될 때 모든 컴포넌트를 미리 생성해야 하므로 초기화가 느렸습니다. 유연성 부족 EJB 비즈니스 로직과 트랜잭션 관리, 로깅 등 여러 기능이 하나의 EJB 안에 혼합되어 있어서 코드 재사용이나 유지보수가 어려웠습니다.
또한 한 곳에 보여있다는 것은 결합도가 높다는 것이고, 첫 번째로 작성한 복잡성과 높은 결합도에 한 몫을 하기도 했습니다.테스트의 어려움 EJB는 애플리케이션 서버 내에서 동작해야 했기 때문에 단위 테스트*를 수행하기가 어려웠습니다. *느린 초기화가 문제가 되는 이유
더보기서버는 항상 기민해야합니다.
왜 그래야 하느냐고 묻는다면
카톡을 보내는데 2초, 3초, 4초... 등 걸린다고 생각해봅시다.
이 애플리케이션을 쓰는 사용자는 짜증이 날겁니다.
거기서 더 나아간다면 카톡을 쓰지 않겠죠.
추가적으로 온 국민이 주시할만큼 심각한 일이 벌어져 카톡량이 증가한다고 생각해봅시다.
그런데 카톡이 보내지지 않는다면 사용자의 불만이 커지겠죠.
때문에 트래픽이 많이 들어와도 그대로 진행되게 해야합니다.
서버가 실행될 때 애플리케이션의 초기화 과정이 길어지면, 그 동안 쌓인 사용자 요청을 처리할 수 없어 병목이 발생합니다.
즉, 초기화가 오래 걸리면 서버가 사용자 요청을 빠르게 처리하지 못하고, 트래픽이 몰릴 때 빠르게 대응하기 어려워진다는 겁니다.
이런 지점들을 EJB는 대처하지 못했습니다.
*단위 테스트의 중요성
더보기단위 테스트는 코드의 각 부분이 예상대로 동작하는지 확인하는 데 중요합니다.
이를 통해 버그를 조기에 발견하고, 코드 변경 후에도 기존 기능이 정상 작동하는지 보장할 수 있습니다.
로드 존슨은 EJB의 한계를 개선함과 동시에 개발을 단순화하기 위해 Spring 프레임워크를 만들어냅니다.
EJB에는 복잡성과 높은 결합도, 무거운 컨테이너, 느린 초기화, 유연성 부족, 테스트의 어려움을
Spring 프레임워크에서는 의존성 주입(Dependency Injection, DI), 경량화된 컨테이너, 지연 로딩(Lazy Initialization), 의존성 주입(Dependency Injection, DI), 모듈화와 AOP(Aspect-Oriented Programming) 지원, 테스트 용이성으로 해결하고자 했습니다.
(1) 복잡성과 높은 결합도 -> 의존성 주입(DI)과 설정 단순화
- 클래스 A가 클래스 B에 의존한다면 B 객체를 먼저 생성해야하는 순서에 제약이 생깁니다.
EJB를 사용할 때는 개발자가 JNDI(Java Naming and Directory Interface)를 이용해 수동으로 의존성을 해결해야 했습니다.
=> Spring IoC 컨테이너라는 개념을 통해, 개발자가 하던 객체 관리를 Spring IoC 컨테이너에 맡겨 복잡성을 해결했습니다.
IoC는 Inversion of Control의 약자로, 간단히 말하자면 "개발자가 하지 않게 하는 것"에 대한 개념입니다.
또한 외부(Spring IoC 컨테이너)에서 필요한 의존성을 주입받아 객체 간의 결합도도 낮아졌습니다.
(2) 무거운 컨테이너 -> 경량화된 컨테이너
- EJB의 컨테이너는 단순 객체 관리를 넘어 무거운 기능까지 모두 컨트롤했고, 컨테이너는 무거워졌으며, 리소스를 많이 쓰고, 초기화가 느리고, 특정 서버에 종속적인 형태가 되어버렸습니다.
=> Spring IoC 컨테이너는 핵심적인 객체(Bean)만 관리하고, 필요하면 다른 기능을 추가할 수 있도록 가볍게 설계되어 있습니다. 때문에 특정 서버에 종속되지 않습니다.
(3) 느린 초기화 –> Lazy Initialization
- EJB는 애플리케이션이 시작될 때 모든 컴포넌트를 미리 생성해야 하므로 초기화가 느렸습니다.
=> Spring은 필요할 때만 객체를 생성하는 지연 로딩(Lazy Initialization) 기능을 지원합니다. 이를 통해 애플리케이션의 초기 로딩 속도가 개선돼 서버 자원을 효율적으로 사용할 수 있게 됐습니다.
(4) 유연성 부족 -> 모듈화와 AOP 지원
- EJB 비즈니스 로직과 트랜잭션 관리, 로깅 등 여러 기능이 하나의 EJB 안에 혼합되어 있어서 코드 재사용이나 유지보수가 어려웠습니다.
=> Spring은 AOP(Aspect-Oriented Programming) 개념을 도입해서, 트랜잭션이나 로깅과 같은 횡단관심사(코드의 앞뒤로 반복적으로 들어가는 부수적인 기능)를 핵심 비즈니스 로직과 분리했습니다.
(5) 테스트의 여러움 -> 테스트를 용이하게!
- EJB는 애플리케이션 서버 내에서 동작해야 했기 때문에 단위 테스트를 수행하기가 어려웠습니다.
=> Spring은 POJO 기반으로 설계되어 있어, 애플리케이션 서버 없이도 단위 테스트를 쉽게 수행할 수 있습니다.
또한 JUnit, Mockito와 같은 다양한 테스트 도구와의 연동이 원활하여 테스트 작성 및 실행이 용이합니다.
'Spring&SpringBoot' 카테고리의 다른 글
Spring Boot 애플리케이션 설정과 DB 설정 (0) 2025.02.27 Spring MVC @Controller와 @RestController의 차이점 (0) 2025.02.17 Spring에서 AOP(Aspect Oriented Programming)가 필요한 이유 (0) 2025.02.17 Spring Boot에서 사용되는 다양한 Bean 등록 방법 (0) 2025.02.10 Gradle을 사용한 Spring Boot 프로젝트의 구조와 설정 (1) 2025.01.31 - 클래스 A가 클래스 B에 의존한다면 B 객체를 먼저 생성해야하는 순서에 제약이 생깁니다.