EJB(Enterprise JavaBeans)는 웹 개발을 위해 EJB 컨테이너가 트랜잭션, 보안, 세션 관리 등 공통 인프라를 처리하고, 개발자는 비즈니스 로직만 구현하는 방식으로 구현하는 자바 기반 서버 컴포넌트 기술이다.
EJB는 비즈니스 로직을 담당하는 부품이며, 컨테이너는 데이터베이스 처리, 트랜잭션 처리 등 시스템 서비스를 제공하는 실행 환경을 제공하며 비즈니스 로직과 시스템 서비스를 분리하여 효율적이고 표준화된 엔터프라이즈 애플리케이션 개발 방법을 지원했다.
EJB는 복잡한 설정과 무거운 컨테이너 구조로 인해 개발과 배포가 번거롭고, 특히 JBoss와 같은 특정 애플리케이션 서버 환경에 맞춰 설정과 최적화를 별도로 수행해야 하는 부담이 컸다.
또한 벤더 별 애플리케이션 서버 구현 차이로 코드가 특정 기술에 종속되어 이식성과 호환성이 떨어졌다.
이로 인해 개발자는 표준화된 규약을 따르면서도 JBoss 등 개별 서버 환경에 맞춘 제약을 해결해야 하는 이중의 어려움을 겪었다.
Spring은 2002년 Rod Johnson이 저서 "Expert One-on-One J2EE Design and Development"에서 제시한 아이디어를 바탕으로 등장하였다. 이는 EJB의 복잡성과 무거움을 대체할 가벼운 프레임워크 필요성에서 출발하였으며, 의존성 주입(DI)과 AOP(Aspect Oriented Programming)를 통해 엔터프라이즈 애플리케이션의 설계 복잡성을 낮췄다. 또한 실제 프로젝트 사례를 기반으로 문제를 해결하는 실용적 접근을 도입하여 개발자 친화적 환경을 제공하였다.
Spring Framework는 Java EE 애플리케이션 개발을 지원하는 오픈소스 프레임워크로, 2003년에 공개되었다. 본래 목적은 EJB의 복잡성을 대체하는 가벼운 컨테이너로서 객체 관리와 트랜잭션, 보안, AOP 등을 지원하는 것이었으며, 이후 Spring MVC를 통해 웹 애플리케이션 개발로 확장되었다.
웹 개발 시 동적 웹 사이트 구현을 위한 다양한 모듈을 제공하며, 전자정부 표준 프레임워크의 기반 기술로 활용되고 있다. Java EE(Servlet) 기반에서 동작하며, IoC (Inversion of Control, 제어의 역전)과 관점 지향 프로그래밍(AOP)을 통해 설계 품질과 생산성을 크게 향상시켰다.
| DI (Dependency Injection) 의존성 주입 | 설정 파일이나 어노테이션을 통해 객체 간의 의존 관계를 설정하여 개발자가 직접 의존하는 객체를 생성할 필요가 없다. → 코드 관점으로는 Spring에서는 new를 거의 사용하지 않는다. |
|---|---|
| Spring AOP (Aspect Oriented Programming) 관점 지향 프로그래밍 | 트랜잭션, 로깅, 보안 등 여러 모듈, 여러 계층에서 공통으로 필요로 하는 기능의 경우 해당 기능들을 기존 코드와 분리하여 관리가 가능한 기능. → 부가적인 기능 코드를 분리하여 비즈니스 로직에 집중할 수 있다. |
| POJO (Plain Old Java Object) | 특정 프레임워크나 기술에 종속되지 않은 순수한 자바 객체를 사용하여 단순하고 이해하기 쉬운 애플리케이션 구조를 구현한다. → EJB와 달리 서버 없이 순수 Java 프로그램으로도 실행이 가능하다. |
| IoC (Inversion of Control) 제어 반점 | 컨트롤의 제어권이 개발자가 아니라 프레임워크에 있다는 뜻으로 객체의 생성부터 모든 생명주기의 관리까지 프레임워크가 주도 객체를 생성하고 직접 호출하는 프로그램이 아니라 만들어 둔 자원을 호출하여 사용 → 객체 생성과 소멸 정리는 모두 Spring에서 담당한다. |


POJO는 특정 프레임워크나 기술에 종속되지 않는 순수한 자바 객체를 의미한다.
이를 통해 비즈니스 로직이 기술적 제약 없이 독립적으로 구현될 수 있어 코드의 단순성과 유지보수성이 높아지고 애플리케이션의 구조적 유연성과 테스트 용이성을 확보할 수 있다.
→ Spring을 Web이 아닌 프로젝트로 구성하는 경우 Java만 있어도 실행 가능하다. 해당 메커니즘은 서버가 없어도 Java 실행을 통해 Junit 기반으로 Test를 수행 할 수 있도록 도와준다.
스프링은 SOLID 객체지향 설계 원칙 준수하도록 설계되었다. 이는 개발자 코드에도 영향을 미친다.
DRY(Don’t Repeat Yourself) 원칙: 중복 코드를 최소화하여 유지보수성과 재사용성을 높인다.
단일 책임 원칙(SRP): 각 객체가 하나의 책임만 가지도록 하여 변경에 유연하고 명확한 구조를 유지한다.
관심사의 분리: 비즈니스 로직과 공통 기능을 분리하여 모듈화와 확장성을 강화한다.
Spring은 JUnit과 Mockito와 같은 도구를 활용해 TDD(Test-Driven Development) 기반 개발을 지원한다.
이를 통해 단위 테스트를 손쉽게 작성하고 통합 테스트를 수행할 수 있다. 또한 테스트 커버리지 측정을 통해 코드 품질을 지속적으로 검증·향상할 수 있는 환경을 제공한다.
TDD(Test-Driven Development): 테스트 코드를 먼저 작성한 뒤 그 테스트를 통과하는 기능을 구현하는 개발 방식
IoC는 객체 생성과 의존성 관리의 제어 권한을 개발자가 아닌 컨테이너가 담당하는 개념이다.
IoC 컨테이너는 객체를 생성·초기화·주입하며 애플리케이션 전반의 의존성을 관리한다.
이를 통해 객체의 생명주기 관리가 일원화되고, 코드의 결합도가 낮아져 유지보수성과 확장성이 향상된다.
→ Spring에서는 XML과 어노테이션 기반으로 설정 정보를 설정하는데 가장 많이 활용되던 기능이다.
Bean은 Spring 컨테이너가 생성· 관리하는 객체로, 애플리케이션의 핵심 기능을 담당하는 구성 요소이다.
Spring 컨테이너는 Bean의 생성, 의존성 주입, 생명주기를 관리하며 애플리케이션 전반의 동작을 조율한다.
Bean은 특정 규약에 종속되지 않은 POJO로 정의되며, 이를 통해 단순성과 유연성을 유지한다.
→ Bean은 EJB에서도 존재하였던 기능이나 Spring과 다른 점은 EJB의 Bean은 서버 어플리케이션에서
생성되었으나 Spring에서는Spring Context에서 Bean이 생성되고 관리된다.
DI는 객체가 필요로 하는 의존성을 외부에서 주입하여 코드 내 직접 생성 의존성을 제거하는 방식이다.
이를 통해 객체 간 결합도를 낮춰(느슨한 결합) 변경과 확장이 용이 해진다. 결과적으로 유연하고
테스트하기 쉬운 설계를 가능하게 한다.
→ DI를 통해 사용자는 객체간 의존성 관리를 수행하지 않아도 Spring에서 알아서 객체를 연결해준다.
AOP는 공통 기능을 핵심 비즈니스 로직과 분리해 모듈화하는 관점 지향 프로그래밍 기법이다.
로깅, 트랜잭션, 보안 등 횡단 관심사(Cross-cutting Concerns)를 분리하여 비즈니스 로직에 집중할수 있다.
Spring AOP는 트랜잭션 관리, 로깅, 예외 처리 등 공통 기능을 런타임에 유연하게 적용하는 데 활용된다.
→ 간단한 어노테이션 설정 만으로도 특정 패키지에 해당되는 패턴에 전후단으로 로직 구성이 가능
Spring 프로젝트 생태계는 경량화된 애플리케이션 개발을 위한 오픈소스 프레임워크 집합으로, 다양한 모듈을 통해 엔터프라이즈 개발을 지원한다. Spring Framework를 중심으로 Boot, Data, Security, Cloud 등 다양한 하위 프로젝트들이 통합적으로 제공되며 이를 통해 유연한 아키텍처, 빠른 개발 생산성, 클라우드/마이크로서비스 환경 최적화를 실현할 수 있다.

Spring 공식 홈페이지에서 스프링 프레임워크(모듈)별로 공식 문서를 제공하며 개발자를 돕고 있다.