프레임워크(Framework)는 애플리케이션 개발 시 공통적으로 사용되는 구조와 기능들을 미리 제공하여, 개발자가 비즈니스 로직에 집중할 수 있도록 도와주는 뼈대 혹은 틀입니다.
<프레임워크의 장점>
- 반복적인 코드 최소화
- 일관된 아키텍처 제공
- 생산성 향상
- 코드의 재사용성과 유지보수 용이성
Spring은 자바 생태계에서 가장 많이 쓰이는 대표적인 프레임워크로, 웹, 데이터베이스, 보안, 테스트 등 전 영역을 포괄합니다. 이번 글에서는 이런 Spring의 전반적인 개념에 대해 정리해보고자 합니다.
Spring 프레임워크
Java 기반의 엔터프라이즈급 어플리케이션을 만들기 위한 오픈소스 프레임워크로, 객체 지향 프로그래밍(OOP)을 더 잘 활용할 수 있도록 돕습니다. 복잡한 웹 애플리케이션의 개발을 단순화시키는 것이 목적이며, 모듈화된 구조로 필요한 기능만 선택적으로 사용할 수 있습니다.
Spring의 핵심 목표는 개발자가 비즈니스 로직에 집중할 수 있도록 인프라 관련 작업을 처리해주는 것이며, POJO(Plain Old Java Object) 기반의 개발을 권장합니다.
POJO(Plain Old Java Object)
- 특별한 규약(예: 특정 상속, 어노테이션, XML 설정 등)에 따르지 않는 순수한 자바 객체
- getter/setter, 생성자, toString() 등 기본 기능만 가진 클래스
스프링은 이러한 POJO 객체들을 스프링 컨테이너에서 관리하여 개발자가 프레임워크에 종속되지 않고 자유롭게 개발할 수 있도록 합니다.
Spring 모듈 구조
Spring 프레임워크는 다양한 기능을 각각의 모듈(Module)로 분리해 제공합니다. 모듈이란 특정 기능을 담당하는 독립적인 단위이며, 필요한 기능만 선택적으로 사용할 수 있도록 구성되어 있습니다.
아래와 같은 모듈 구조 덕분에 스프링은 유연하고 확장 가능한 애플리케이션 개발이 가능합니다.
| 분류 | 주요 모듈 | 설명 |
| Core Container | Core, Beans, Context, Expression Language | IoC/DI 기반 핵심 기능 (의존성 주입, Bean 관리 등) |
| AOP | AOP | 로깅, 보안, 트랜잭션과 같은 공통 관심사 분리 |
| Data Access | JDBC, ORM, Transactions | 데이터베이스 접근 및 트랜잭션 처리 지원 |
| Web | Web, Web MVC | 웹 애플리케이션 및 REST API 개발 |
| Test | Test | 단위/통합 테스트 지원 (Mock, 컨텍스트 로딩 등) |
Spring 용어 정리
- Bean: 스프링 컨테이너가 생성하고 관리하는 객체
- ApplicationContext: 전체 애플리케이션을 구성하는 스프링 컨테이너 (Bean 관리, 설정, AOP 등 포함)
- IoC Container: 객체의 생성과 관리를 담당하는 컨테이너 → ApplicationContext가 대표적
- Component Scan: 특정 패키지를 탐색하여 자동으로 Bean으로 등록하는 기능 (@Component, @Service, @Repository 등)
- Auto Configuration: 스프링 부트에서 사용하는 자동 Bean 설정 기능
Spring 제공 기능
- 의존성 주입(DI)
- AOP(관점 지향 프로그래밍)
- 트랜잭션 관리
- MVC 웹 프레임워크
- JDBC, ORM 지원 등 데이터 접근 기능
Spring 장점
- 생산성 ↑: DI, AOP, 어노테이션 설정 등으로 코드 간결
- 유지보수 ↑: 관심사 분리, 모듈화, 계층 분리
- 테스트 용이: 의존성 주입 구조로 Mock 객체 사용 용이
Bean과 ApplicationContext
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
OrderService orderService = context.getBean(OrderService.class);
Bean
스프링 컨테이너가 생성하고 관리하는 자바 객체입니다. 일반적으로 개발자가 작성한 클래스에 @Component, @Service, @Repository 등의 어노테이션을 붙여 등록합니다.
Bean 생명주기 단계
- 등록: @Component, @Bean
- 의존성 주입: @Autowired
- 초기화: @PostConstruct
- 소멸: @PreDestroy
ApplicationContext
- Bean을 생성하고 관리하는 스프링의 핵심 컨테이너
스프링 컨테이너의 핵심 인터페이스로, Bean 등록/생성/조회 등을 담당합니다.
ApplicationContext는 BeanFactory의 상위 개념으로, 아래와 같은 부가 기능도 제공합니다.
- 국제화 메시지 처리
- 이벤트 전파
- AOP 연동 지원
- Bean 생명주기 인터페이스 지원
Spring MVC 아키텍처
- Spring MVC는 Model-View-Controller 패턴을 따르는 웹 프레임워크
- 3계층 아키텍처: Controller → Service → Repository
- @Controller는 요청을 받고, @Service는 로직 처리, @Repository는 DB와 통신
- 역할 분리로 유지보수, 테스트 용이
- 단일 책임 원칙에 맞춘 구조
- Spring MVC는 REST API 작성도 자연스럽게 지원하며, @RestController, @ResponseBody, @RequestBody 등을 사용
<3계층 아키텍처>
- Controller: 클라이언트 요청을 받고 응답 처리 (프레젠테이션 계층)
- Service: 비즈니스 로직 처리 (비즈니스 계층)
- Repository: 데이터베이스 접근 처리 (영속성 계층)
Spring MVC는 흔히 3계층 아키텍처라고 불리는 구조를 따릅니다. 위와 같은 구조는 역할을 분리해서 유지보수성과 테스트를 좋게 만듭니다. 이것이 바로 단일 책임 원칙(SRP)에 부합합니다.
<핵심 컴포넌트>
Spring MVC에서 핵심 컴포넌트는 프레임워크가 내부적으로 사용하는 주요 구성 요소들을 말합니다. 각 컴포넌트는 MVC 흐름의 한 단계에 관여합니다.
| 컴포넌트 | 역할 |
| DispatcherServlet | 프론트 컨트롤러. 모든 요청의 진입점으로 요청을 받아 다른 컴포넌트로 위임 |
| HandlerMapping | 어떤 컨트롤러가 요청을 처리할지 매핑 정보 탐색 |
| Controller | 실제 요청을 처리하고, 결과(Model과 View)를 반환 |
| ViewResolver | 컨트롤러가 반환한 View 이름을 기반으로 실제 View 객체 결정 |
| View | 최종적으로 클라이언트에게 응답을 보여주는 HTML, JSON 등 렌더링 담당 |
<요청 처리 흐름>
- 클라이언트가 요청을 보냄
- DispatcherServlet이 요청을 받음
- HandlerMapping이 적절한 Controller 탐색
- Controller에서 Service, Repository를 호출해 비즈니스 처리
- Controller가 Model + View 이름을 반환
- ViewResolver가 실제 View 파일(.jsp, .html 등)을 결정
- View를 렌더링해서 클라이언트에 응답

- 클라이언트 요청이 DispatcherServlet에 도착
- DispatcherServlet은 핸들러 매핑을 통해 적절한 컨트롤러를 찾고 실행
- 컨트롤러는 서비스, 레포지토리를 거쳐 DB와 통신한 후 모델 데이터를 반환
- ViewResolver가 알맞은 View를 선택하고, 렌더링된 결과가 사용자에게 전달
Spring의 주요 특징
- IoC(제어의 역전)와 DI(의존성 주입)
객체 생성 및 의존성 주입을 개발자가 아닌 스프링 컨테이너가 담당하는 철학으로, 유연성과 테스트 용이성을 높입니다.- IoC(제어의 역전)
- 객체 간의 결합도를 낮추고 모듈성을 높이는 핵심 메커니즘
- 객체 생성과 관리를 Spring IoC 컨테이너가 자동으로 처리
- XML, Java Config, Annotation 기반 설정 지원
- 장점: 코드의 재사용성 증가, 테스트 용이성 향상, 느슨한 결합 달성
- DI(의존성 주입)
- 객체의 생명주기 관리를 개발자가 아닌 Spring 컨테이너가 담당
- 객체 생성, 초기화, 소멸 과정을 프레임워크가 제어
- 개발자는 비즈니스 로직에 집중 가능
- IoC(제어의 역전)
- AOP (Aspect-Oriented Programming, 관점 지향 프로그래밍)
로깅, 트랜잭션 관리 등 공통 기능을 분리하여 핵심 로직을 깔끔하게 유지할 수 있도록 합니다.- 횡단 관심사(로깅, 보안, 트랜잭션 등)를 모듈화
- 핵심 비즈니스 로직과 부가 기능의 분리
- 프록시 기반의 AOP 지원
- 코드 중복 최소화 및 모듈성 향상
- 어노테이션 기반 설정과 컴포넌트 스캔
- XML 기반 설정의 복잡성과 번거로움을 해결
- 코드와 설정의 결합도를 높이고 가독성 향상
- 개발자의 설정 부담을 획기적으로 감소
- 강력한 MVC 아키텍처
- 웹 애플리케이션 개발을 위한 구조화된 아키텍처 제공
- DispatcherServlet을 통한 중앙집중식 요청 처리
- 컨트롤러, 서비스, 레포지토리 계층의 명확한 분리
- ORM 통합
- Hibernate, JPA 등 다양한 ORM 프레임워크와의 seamless 통합
- JdbcTemplate을 통한 간편한 데이터베이스 작업
- 컨트롤러, 서비스, 리포지토리 계층의 명확한 분리
- 테스트 지원
- 단위 테스트와 통합 테스트를 위한 포괄적인 지원
- @Test, @MockBean 등의 어노테이션을 통한 쉬운 테스트 작성
- Spring Boot Test 모듈로 더욱 간편해진 테스트 환경
- 보안 프레임워크
- Spring Security를 통한 강력한 인증 및 권한 부여 메커니즘
- OAuth, JWT 등 다양한 인증 방식 지원
- 보안 설정의 유연성과 확장성
- 마이크로서비스 아키텍처 지원
- Spring Cloud를 통한 분산 시스템 개발 지원
- 서비스 디스커버리, 로드밸런싱, 서킷브레이커 등 기능 제공
- 클라우드 네이티브 애플리케이션 개발에 최적화
1. IoC(제어의 역전)와 DI(의존성 주입)
IoC (Inversion of Control)
- 객체 제어권을 개발자가 아닌 스프링이 관리
- DI, AOP는 IoC 구현 방법
IoC는 제어 흐름의 주도권을 개발자 코드가 아닌 프레임워크(스프링 컨테이너)가 가지는 개념입니다. 이를 통해 객체 간 결합도를 줄이고 유연한 구조를 구성할 수 있습니다. 또한 객체의 생성, 의존성 주입, 생명주기 관리 등을 컨테이너가 담당함으로써 애플리케이션의 유연성과 테스트 용이성을 높입니다.
DI (Dependency Injection)
- 의존성을 외부에서 주입
- DI는 IoC를 구현하는 가장 대표적인 방법
DI는 IoC를 구현하는 가장 대표적인 방법입니다. 객체가 자신의 의존성을 내부에서 생성하는 대신, 외부(스프링 컨테이너) 에서 주입받아 사용하도록 합니다.
<DI의 장점>
- 결합도 감소 (유지보수성과 확장성 향상)
- 테스트 용이성 (Mock 객체 주입 가능)
- 객체 간 명확한 역할 분리 및 의존성 관리
생성자 주입 예시
@Component
public class OrderService {
private final PaymentService paymentService;
@Autowired
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
세터 주입 예시
@Component
public class OrderService {
private PaymentService paymentService;
@Autowired
public void setPaymentService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
2. AOP (Aspect-Oriented Programming, 관점 지향 프로그래밍)
- 로깅, 트랜잭션, 보안처럼 공통 기능을 핵심 로직과 분리하여 모듈화하는 방식
- 핵심 로직과 분리하여 유지보수 ↑
- 핵심 어노테이션: @Aspect , @Before, @After, @Around
AOP는 핵심 비즈니스 로직 외에 공통적으로 반복되는 부가 로직(로깅, 보안, 트랜잭션 등)을 분리하여 재사용성과 유지보수성을 향상시키는 프로그래밍 방식입니다.
<AOP의 주요 용어>
- Aspect: 공통 기능 모듈 (e.g. LoggingAspect)
- Join Point: 실행 지점 (e.g. 메서드 호출)
- Advice: 실행될 코드 (e.g. @Before, @After)
- Pointcut: Advice가 실행될 조건 지정
- Weaving: Advice를 실제 코드에 적용하는 과정
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Method called: " + joinPoint.getSignature().getName());
}
}
3. 어노테이션 기반 설정과 컴포넌트 스캔
어노테이션
<bean id="orderService" class="com.example.OrderService"/>
스프링에서는 위와 같이 원래 XML 파일로 Bean 설정을 했습니다.
하지만 XML이 많아지면 복잡해지기 때문에, 요즘은 아래와 같 Java 코드에서 어노테이션을 활용한 설정을 선호합니다.
@Component
public class OrderService {}
Spring 주요 어노테이션 정리
| 어노테이션 | 설명 |
| @Component | 일반적인 컴포넌트 클래스 (기본형) |
| @Service | 비즈니스 로직 계층에서 사용 |
| @Repository | DAO 계층, 예외 변환 지원 |
| @Controller | 웹 요청을 처리하는 MVC 컨트롤러 |
| @RestController | @Controller + @ResponseBody, REST API용 컨트롤러 |
| @Autowired | 스프링이 자동으로 의존성 주입 |
| @PostConstruct, @PreDestroy | 객체 초기화 및 소멸 시점에 실행되는 콜백 메서드 지정 |
컴포넌트(Component)
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {}
스프링에서 컴포넌트는 스프링 컨테이너가 관리하는 객체(Bean)를 말합니다. 일반적으로 @Component 또는 그 하위 어노테이션(@Service, @Repository, @Controller)이 붙은 클래스는 컴포넌트로 간주되며, 자동으로 스프링 컨테이너에 등록됩니다.
- 컴포넌트는 객체를 개발자가 직접 생성하지 않고, 스프링이 생성하여 관리 (IoC 개념 기반)
- 자동 등록을 위해 @ComponentScan 어노테이션을 사용하며, 지정한 패키지 이하에서 해당 어노테이션이 붙은 클래스를 찾아 Bean으로 등록
- @ComponentScan 으로 자동으로 빈을 등록할 수 있음
- 어노테이션을 통한 빈 자동 감지
- @Component, @Service, @Repository, @Controller, @RestController
- 특정 계층별 역할에 따라 명시적 표현 가능
Spring Boot의 등장과 목적
Spring Boot는 Spring의 철학과 기능을 유지하면서, 개발자가 빠르게 시작하고 운영할 수 있도록 돕는 프레임워크입니다.
기존 Spring 프레임워크는 설정(xml, 자바 기반 설정 등)이 많고 복잡하여 진입장벽이 높았습니다.
Spring Boot는 Spring의 설정을 간소화하고, 애플리케이션 개발과 배포를 빠르게 할 수 있도록 지원합니다.
주요 특징
- 내장 서버(Tomcat, Jetty 등) 지원 → WAR 배포 없이 JAR 실행 가능
- 자동 설정(Auto Configuration) → 대부분의 설정을 자동화
- 스타터 의존성 제공 → 필요한 기능을 모듈 단위로 관리
- 운영 도구 내장 (Actuator, Metrics 등)
Spring과 Spring Boot의 차이점
| 항목 | Spring Framework | Spring Boot |
| 설정 방식 | 수동 설정 (XML, JavaConfig) | 자동 설정 중심 |
| 서버 구성 | 외부 WAS 사용 | 내장 WAS 제공 |
| 시작 속도 | 상대적으로 느림 | 빠르게 프로젝트 시작 가능 |
| 프로젝트 구조 | 자유도 높음 | 관례 중심 구조 제공 |
| 의존성 관리 | 수동 설정 | Starter로 간단하게 구성 |
[참고자료]
https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/overview.html
'Backend > Spring' 카테고리의 다른 글
| [JPA] 동시성 제어 - 낙관적 락(Optimistic Lock), 비관적 락(Pessimistic Lock) (0) | 2025.02.28 |
|---|