Spring Framework의 탄생 배경과 해결하고자 했던 문제점
1. Spring Framework의 등장 배경
- 2000년대 초반, Java 기반의 엔터프라이즈 애플리케이션 개발에서는 J2EE(Java 2 Enterprise Edition)가 표준으로 사용되었다.
- 특히, J2EE의 핵심 기술 중 하나인 EJB(Enterprise JavaBeans)는 대규모 애플리케이션 개발을 위한 강력한 기능을 제공했으나, 다음과 같은 문제점이 존재했다.
1) 설정이 복잡하고 실행 속도가 느림
2) 배포 과정이 번거로움
3) JNDI 조회, 원격 호출 등으로 인해 개발 및 유지보수가 어려움
=> 이러한 문제를 해결하기 위해 Spring Framework가 등장했으며, 보다 가볍고 유연한 Java 애플리케이션 개발 환경을 제공하는 것목표로 함.
2. Spring Framework가 해결하고자 했던 문제점
1) EJB의 복잡성과 무거운 실행 환경
기존 J2EE에서는 EJB 컨테이너를 사용해야만 트랜잭션 관리, 분산 시스템, 보안 기능 등을 활용할 수 있었으나,
이 과정에서 설정이 복잡하고 실행 속도가 느려지는 문제가 발생했다.
- 개발자는 여러 설정 파일과 복잡한 인터페이스를 구현해야 했다.
- EJB 설정은 주로 XML 파일을 통해 이루어졌고, 이는 유지보수를 어렵게 만들었음.
- 또, EJB의 컨테이너는 매우 무겁고 리소스를 많이 소모 -> 초기화가 느려지고, 배포와 관리가 어려워짐
Spring
POJO(Plain Old Java Object) 기반 개발 지원 → EJB 없이도 경량 컨테이너에서 실행 가능하도록 개선 (특정 프레임워크에 결합 X)
Spring 컨테이너를 활용하여 애플리케이션 서버 없이도 독립적으로 실행 가능하도록 지원
다양한 설정 방식을 지원 (XML, 자바 코드, Annotation)
2) 강한 의존성과 유지보수 문제
- J2EE 환경에서는 클래스 간 결합도가 높아(Tightly Coupled) 코드 변경 시 유지보수가 어려운 문제가 있었음. (특정 아키텍처와 강하게 결합)
- 예를 들어, 특정 서비스 클래스가 데이터베이스 접근 객체를 직접 생성하여 사용하면,
데이터베이스 접근 방식이 변경될 경우 서비스 클래스도 함께 수정해야 하는 비효율성이 존재했다.
Spring
IoC(Inversion of Control, 제어의 역전) 적용 → 객체의 생명주기 및 의존성 관리를 프레임워크가 담당하도록 개선
DI(Dependency Injection, 의존성 주입) 지원 → 객체 간 결합도를 낮추어 테스트와 유지보수를 용이하게 함
=> 코드를 변경하더라도, 결합도가 낮아 해당하는 부분만 수정해도 문제가 없다!
3) 공통 기능(로깅, 보안, 트랜잭션) 중복 문제
- OOP(Object-Oriented Programming)에서는 트랜잭션 관리, 로깅, 보안 등의 공통 기능을 여러 클래스에서 중복 구현해야 하는 문제가 발생했음.
- 이로 인해 코드가 복잡해지고 유지보수가 어려워지는 문제가 있었다.
Spring
AOP(Aspect-Oriented Programming, 관점 지향 프로그래밍) 도입
→ 공통 기능을 별도로 관리하여 핵심 비즈니스 로직과 분리하도록 개선
로깅, 트랜잭션, 보안 등의 공통 기능을 애플리케이션 코드와 분리하여 관리 가능하도록
=> 횡단 관심사를 효과적으로 관리하여 코드의 중복을 줄이고 유지보수를 용이하도록 함!
4) 트랜잭션 관리의 어려움
- J2EE 환경에서는 JDBC, Hibernate, JPA 등 데이터 접근 기술마다 트랜잭션 관리 방식이 다른 문제점이 있었다.
- 특히, 트랜잭션 관리를 위해 EJB를 사용할 경우 설정이 복잡하고 성능 저하 문제가 발생했음.
Spring
일관된 트랜잭션 관리 방식 제공 (@Transactional 애너테이션 활용)
JDBC, Hibernate, JPA 등 다양한 기술에서 동일한 방식으로 트랜잭션 관리 가능하도록 지원
5) 테스트 환경 구축의 어려움
- EJB 기반 애플리케이션은 EJB 컨테이너 환경에서 실행해야 하므로, 단위 테스트(Unit Test) 수행이 어렵고 실행 속도가 느렸다.
- 테스트를 위해 매번 서버를 실행해야 하는 불편함이 존재!
- 또한, EJB 컨테이너가 필요하여, 테스트 환경 설정이 복잡했음.
Spring
POJO기반의 IoC 컨테이너를 활용하여, 컨테이너 의존성을 최소화하여 독립적인 단위 테스트 가능
Junit과 통합하여 @MockBean 등의 기능을 제공, 테스트 코드 작성을 용이하게 개선
JUnit과 같은 테스트 프레임워클르 사용하여 독립적인 테스트 수행 가능
3. EJB vs Spring

4. 결론
- Spring Framework는 J2EE의 복잡성을 해결하고, 보다 경량화된 Java 애플리케이션 개발 환경을 제공하기 위해 탄생!
- 이를 통해 기존 J2EE 환경에서 발생했던 EJB의 복잡성, 강한 의존성, 공통 기능의 중복, 트랜잭션 관리 문제, 테스트 환경 구축의 어려움 등의 문제를 해결했다.