Spring Framework 시리즈 1화 – Spring Framework 시작하기
Spring Framework는 자바 기반 애플리케이션 개발의 표준입니다. 이 글에서는 Spring이 등장하게 된 배경과 핵심 개념인 IoC, DI의 원리를 실전 예제 중심으로 소개합니다.
왜 Spring Framework인가?
자바로 웹 애플리케이션을 개발해본 적이 있는 개발자라면 JSP, Servlet 기반 개발이 얼마나 번거롭고, 중복 코드가 많으며, 확장성과 유지보수가 어려운지를 한 번쯤 경험해봤을 것입니다.
Spring은 이러한 문제를 해결하기 위해 등장했습니다. 핵심 철학은 단순합니다.
“객체 간의 의존 관계를 자동으로 연결해주고, 개발자는 비즈니스 로직 구현에 집중하게 하자.”
이 철학을 코드로 구현한 것이 바로 **IoC (제어의 역전)**와 **DI (의존성 주입)**입니다. 이 두 가지가 Spring Core의 중심입니다.
IoC(Inversion of Control)란?
전통적인 자바 코드에서는 객체를 사용할 클래스가 직접 객체를 생성합니다.
Engine engine = new Engine();
Car car = new Car(engine);
하지만 이렇게 되면 Car 클래스는 Engine 객체에 강하게 결합되어 있어, 변경이나 테스트가 어렵습니다.
이 문제를 해결하기 위해 등장한 개념이 **제어의 역전(IoC)**입니다. 객체 생성과 생명주기 관리를 개발자가 아닌 프레임워크가 담당하게 함으로써 느슨한 결합(Loosely Coupled)을 유도합니다.
DI(Dependency Injection)의 개념
**의존성 주입(Dependency Injection)**은 IoC를 구현하는 방법 중 하나입니다.
Spring은 객체 간 의존 관계를 설정 파일이나 애노테이션을 통해 정의하고, 런타임에 이 관계를 자동으로 연결합니다.
다시 예를 들어보겠습니다.
기존 방식:
Car car = new Car(new Engine());
DI 방식 (Spring 활용 시):
@Component
public class Engine {}
@Component
public class Car {
private final Engine engine;
@Autowired
public Car(Engine engine) {
this.engine = engine;
}
}
Spring이 Engine 빈을 자동으로 찾아 Car에 주입해줍니다. 개발자는 new 키워드를 사용할 일이 없습니다.
Spring이 제공하는 핵심 기능
Spring은 단순한 DI 컨테이너를 넘어서 다양한 기능을 제공합니다.
기능 영역 설명
Spring Core | IoC/DI 기능의 핵심 |
Spring MVC | 웹 애플리케이션 개발 (Controller/View 처리) |
Spring Security | 인증 및 인가 처리 |
Spring Data | 데이터 접근 계층 통합 (JPA, JDBC 등) |
Spring AOP | 횡단 관심사 처리 (로깅, 트랜잭션 등) |
Spring Boot | 설정 자동화와 내장 톰캣 지원 |
이번 시리즈는 이 중에서도 가장 기본이 되는 Core, MVC, Security를 순서대로 학습합니다.
개발 환경 준비 (필수)
- JDK 17 이상
- Spring Boot 3.x 이상 (우리는 핵심 개념 이해를 돕기 위해 Spring Boot도 일부 병행 활용)
- IDE: IntelliJ, VS Code, Eclipse 등
- 빌드 도구: Gradle or Maven
실습 프로젝트 구조 소개
이 시리즈에서는 모든 예제를 다음 구조를 기반으로 구성합니다:
src/
└── main/
├── java/
│ └── com.example.springcore/
└── resources/
└── application.properties
그리고 Gradle 기준의 build.gradle 예시는 다음과 같습니다:
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.0'
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
}
마무리 – 왜 이 시리즈가 중요한가?
많은 개발자가 Spring Boot만으로 개발을 시작하면서, Spring Core의 철학과 메커니즘을 건너뛰는 경우가 많습니다. 하지만 복잡한 구조나, 대규모 프로젝트, 커스텀 기능이 필요한 시점에서는 Spring Core에 대한 이해가 차이를 만듭니다.
이 시리즈를 통해 다음과 같은 목표를 달성할 수 있습니다.
- Spring의 동작 원리를 코드 수준에서 정확히 이해한다.
- Spring Boot가 자동으로 처리하는 내부 구조를 파악한다.
- 실무에서 마주치는 의존성, 설정, 테스트 이슈를 해결할 수 있는 기반을 만든다.
다음 편에서는 @Component, @Autowired를 활용해 의존성 주입(DI)을 실제로 구현하는 방법을 실습해봅니다.