Framework (프레임 워크)
프레임워크는 애플리케이션을 만들 때 필요한 도구와 기능을 미리 모아놓은 틀이다. 집을 지을 때 망치, 못, 설계도와 같은 도구가 필요하듯이 앱을 만들 때도 반복적으로 필요한 기능들이 있는데, 그것을 미리 준비해 둔 것이 프레임 워크이다.
프레임워크는 앱을 구축하는데 필요한 다양한 소프트웨어를 제공하지만 모든 기능을 다 사용할 필요는 없으며,
만드려는 앱의 요구사항에 따라 필요한 것만 골라서 사용하면 된다.
Spring Framework (스프링 프레임워크)
스프링은 자바 기반의 백엔드 애플리케이션 프레임워크이다. 단순한 라이브러리가 아니라, 백엔드 앱 개발의 전반적인 구조와 방향을 잡아주는 역할을 하며 특히 웹 서비스나 서버 프로그램을 만들 때 가장 많이 사용되는 프레임워크 중 하나이다.
*라이브러리는 개발자가 필요할 때 가져다 사용하지만, 프레임워크는 전체구조를 프레임워크가 관리합니다.
백엔드 애플리케이션은 서버에서 실행되며 클라이언트의 요청을 처리하고 데이터를 관리하는 역할을 한다.
쉽게 말해 사용자는 웹이나 모바일 같은 클라이언트 앱을 통해 서비스에 접근해서 요청하고, 클라이언트 앱은 백엔드에 필요한 데이터 작업을 요청하며 백엔드는 그 요청을 처리하여 응답을 돌려주는 구조이다.
스프링은 이러한 백엔드 구조의 애플리케이션을 구축하는데 필요한 거의 모든 것을 제공한다.
스프링은 다양한 모듈을 제공하지만 그 중심에는 몇 가지 핵심 개념이 있다.
| 모듈 | 역할 |
| MVC(Model-View-Controller) | 클라이언트의 요청을 구조적으로 처리 |
| Data Access | 데이터베이스와의 연동 |
| IoC(Inversion of Control) | IoC 컨테이너를 통해 객체의 생성과 관리를 자동으로 처리 |
*스프링은 하나의 거대한 기능이 아닌 여러개의 모듈로 구성돼 있으며, 모듈은 특정 기능을 담당하는 독립적인 부품을 의미합니다
백엔드 애플리케이션 구조
웹 서비스는 일반적으로 다음과 같은 구조로 동작합니다.
✔ 사용자 -> 클라이언트 (웹 / 모바일) -> 백엔드 애플리케이션 -> 데이터베이스(다른 백엔드 시스템)
----- 온라인 뱅킹 서비스 예시 -----
1. 사용자가 웹 또는 모바일 앱에서 계좌 조회 요청
2. 클라이언트가 서버에 요청 전달
3. 백엔드 애플리케이션이 데이터베이스에서 계좌 정보를 조회
4. 결과를 다시 클라이언트로 전달
이처럼 클라이언트의 요청을 처리하고 데이터를 관리하는 역할을 하는 것이 바로 백엔드 애플리케이션이다.
일반적인 웹 애플리케이션 구조

Controller : 웹 MVC의 컨트롤러 역할
Service : 핵심 비즈니스 로직 구현
Repository : 데이터베이스에 접근, 도메인 객체를 DB에 저장하고 관리
Domain : 비즈니스 도매인 객체 (Ex : 회원, 주문 등 주로 데이터베이스에 저장하고 관리 됨)
Spring Core (스프링 코어)
스프링 코어는 스프링 프레임워크의 가장 핵심이 되는 모듈입니다. 스프링에서 제공하는 대부분의 기능은 이 스프링 코어를 기반으로 동작하기에, 스프링을 제대로 이해하려면 스프링 코어의 개념을 이해하는 것이 중요합니다.
핵심 기능으로는 제어 역전(IoC), 스프링 컨텍스트(Spring Context), 의존성 주입(DI)등이 있습니다.
IoC (Inversion of Control, 제어 역전)
일반적으로 자바 프로그램에서는 아래와 같이 개발자가 직접 객체를 생성하고 관리합니다.
MemberService memberService = new MemberService();
이처럼 개발자가 직접 new 키워드를 사용해 객체를 생성하고 프로그램의 흐름을 제어합니다. 하지만 스프링에서는 이 제어권을 개발자가 아닌 프레임 워크가 가지게 됩니다. 즉 객체를 언제 생성할지, 객체를 어떻게 관리할지, 객체를 어디에 사용할지에 대한 제어를 스프링이 대신 관리합니다. 이를 제어 역전(IoC, Inversion of Control)이라고 합니다.
*여기서 제어란 객체 생성, 메서드 호출, 프로그램의 흐름 관리 등을 의미합니다.
IoC 컨테이너(스프링 컨텍스트)
이러한 IoC를 실제로 구현하는 것이 바로 IoC 컨테이너입니다. 스프링에서는 이 컨테이너를 스프링 컨텍스트(Spring Context)라고 부릅니다. 개발자가 객체를 스프링 컨텍스트에 등록해 두면, 스프링이 해당 객체를 생성하고 관리하며 필요한 곳에 자동으로 전달해 줍니다. 이렇게 스프링이 관리하는 객체를 스프링 빈(Spring Bean)이라고 합니다.
Spring Bean (스프링 빈)
스프링에서 스프링 컨테이너가 생성하고 관리하는 객체를 스프링 빈(Spring Bean)이라고 합니다. 스프링 빈은 보통 어노테이션을 통해 등록하며 대표적인 어노테이션은 다음과 같습니다.
| 어노테이션 | 역할 |
| @Controller | 웹 요청을 처리하는 컨트롤러 |
| @Service | 비즈니스 로직 처리 |
| @Repository | 데이터베이스 접근 |
| @Component | 일반적인 스프링 빈 |
예를 들어 다음과 같은 코드가 있다고 가정하겠습니다
@Service
public class MemberService {
}
이 경우 스프링이 애플리케이션 실행 시 MemberService 객체를 생성하고, 스프링 컨테이너에 등록합니다.
이렇게 등록된 객체는 필요한 곳에서 자동으로 사용할 수 있습니다.
스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다.
즉 유일하게 하나만 등록해서 공유하며, 따라서 같은 스프링 빈이면 모두 같은 인스턴스이다.
Spring Bean 장점
스프링 빈을 사용하면 아래와 같은 장점이 있습니다.
✔ 객체 관리 자동화 : 스프링이 객체 생성과 관리를 대신해줍니다.
✔ 의존성 관리 : 객체 간의 의존 관계를 스프링이 자동으로 연결해 줍니다.
↓
ex) Controller → Service → Repository
위와 같은 구조에서 각 객체를 직접 생성하지 않아도 스프링이 자동으로 연결해줍니다.
또한 스프링이 관리하는 객체이기 때문에 AOP, 트랜잭션 및 라이프사이클 관리 같은 기능들을 사용할 수 있습니다.
| 기능 | 설명 |
| AOP (Aspect-Oriented Programming) |
관점 지향 프로그래밍을 의미하며, 공통 기능(로그 기록, 실행 시간 측정 등)을 여러 코드에 반복 작성하지 않고 한 곳에서 자동으로 적용 *공통 관심 사항(cross-cutting concern), 핵심 관심 사항(core concern)으로 나뉨. |
| 트랜잭션 | 데이터베이스 작업을 하나의 묶음으로 처리하여 일부만 실행되지 않도록 보장 |
| 라이프사이클 관리 | 스프링이 객체의 생성 -> 초기화 -> 종료 과정까지 관리 |
DI (Dependency Injection, 의존성 주입)
스프링에서 객체를 관리하는 것과 함께 중요한 개념이 의존성 주입(DI)입니다. 의존성(Dependency)이란 뭘까요?
다음 구조와 같이, 어떤 객체가 다른 객체를 필요로 하는 관계를 의존 관계라고 합니다.
Controller → Service → Repository
회원 기능을 처리하는 프로그램이라면 Controller(사용자의 요청받음), Service(실제 비즈니스 로직 처리), Repository(데이터베이스 접근) 이렇게 역할이 나뉘는데, 이때 Controller에게는 Service가, Service에게는 Repository가 필요합니다. 즉, 객체가 다른 객체에 의존하고 있는 구조입니다.
스프링이 없다면 개발자는 아래와 같은 코드로 객체를 생성해야 합니다.
MemberRepository repository = new MemoryMemberRepository();
MemberService service = new MemberService(repository);
MemberController controller = new MemberController(service);
이러한 방식은 객체 생성 코드가 많아지고, 구조가 복잡해지며 객체 변경 시 수정 범위가 커지는 문제가 있습니다.
스프링을 이용한 DI
스프링에서는 객체를 직접 생성하지 않고, 스프링이 스프링 빈을 생성하고 관리하며 필요한 객체를 자동으로 연결해 줍니다.
예시 코드를 보겠습니다.
@Service
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
여기서 MemberRepository 객체를 개발자가 직접 만들지 않았지만, 스프링이 자동으로 객체를 찾아서 넣어줍니다.
이처럼 필요한 객체를 외부에서 넣어주는 것을 의존성 주입(DI, Dependency Injection) 이라고 합니다.
MVC(Model-View-Controller, 모델-뷰-컨트롤러)
백엔드 애플리케이션에서 HTTP 요청을 처리하는 것은 매우 기본적인 기능입니다. 스프링은 이러한 웹 요청을 구조적으로 처리하기 위해 MVC 패턴을 제공합니다. 이 모듈은 애플리케이션의 역할을 세 가지로 나누어 관리하는 디자인 패턴입니다.
| 명칭 | 역할 | 설명 |
| Model | 데이터와 비즈니스 로직 담당 | DB에서 가져온 데이터나 처리 결과를 저장하고 관리 |
| View | 사용자에게 보여지는 화면 담당 | Model이 처리한 데이터를 받아 사용자가 볼 수 있는 형태로 표시 |
| Controller | Model과 View 의 중간 다리 담당 | 사용자의 요청을 받아 적절한 Model을 호출을 하고 그 결과를 View에 전달 |
MVC 동작 흐름
사용자 요청 -> Controller(요청 받아서 처리) -> Model(데이터 처리 및 비즈니스 로직) ->
Controller(결과 받고 View에 전달) -> View (화면에 표시) -> 사용자 응답
Ex) 회원 목록 페이지 요청
1. 사용자가 목록 페이지 요청
2. Controller가 요청 처리
3. Service/Repository 통해 회원 데이터 조회
4. Model에 데이터 담음
5. View가 데이터를 화면에 출력
이처럼 각 역할을 분리하면 수정이 필요한 부분만 변경하면 되기 때문에 유지보수가 훨씬 쉬워집니다. 스프링 MVC는 이러한 구조를 기반으로 웹 요청 처리와 REST API 개발에 널리 사용됩니다.
*REST API는 클라이언트와 서버가 HTTP 통신을 통해 데이터를 주고받는 방식으로, 백엔드에서 가장 많이 사용되는 통신 규칙이다.
Spring Data Access (스프링 데이터 액세스)
애플리케이션을 개발할 때 데이터를 저장하고 조회하는 기능은 필수적입니다. 스프링은 이러한 작업을 쉽게 처리할 수 있도록 데이터 액세스 모듈을 제공합니다.
데이터 액세스는 애플리케이션이 데이터베이스와 상호작용하는 계층을 의미합니다. 일반적으로 애플리케이션이 데이터베이스에 직접 접근하기보다는 Repository와 같은 계층을 통해 간접적으로 접근하도록 구조를 설계하여 보안성과 유지성이 높은 것이 핵심입니다.
또한 스프링 데이터 액세스는 다음과 같은 기술들을 지원합니다.
| 명칭 | 내용 |
| JDBC (Java DataBase Connectivity) |
자바에서 데이터베이스에 직접 접근하는 기본 기술 -SQL 직접 작성 필요 - Connection, Statement, ResultSet 등 직접 작성 |
| ORM (Object Relationl Mapping) |
자바 객체와 데이터베이스 테이블을 자동으로 매핑해주는 기술 즉, 데이터베이스의 데이터를 객체 형태로 다룰 수 있도록 해줍니다. - SQL을 직접 작성하지 않아도 자바 코드만으로 DB를 다룰 수 있음 |
| JPA (Java Persistence API) |
자바에서 ORM을 사용하기 위한 표준 인터페이스 즉 JPA는 기능을 직접 구현한 것이 아닌, ORM을 사용하기 위한 표준을 정의한 것. - 대표적인 구현체 : Hibernate |
| Hibernate | JPA를 구현한 대표적인 ORM 프레임워크 개발자가 작성한 자바 객체(Entity)를 기반으로 데이터베이스 테이블과 매핑 수행 - 내부적으로 SQL을 자동으로 생성 후 실행 |
| Sprig Data JPA | JPA를 더 편리하게 사용할 수 있도록 스프링에서 제공하는 라이브러리 - Repository 인터페이스만 정의해도 기본적인 CRUD 기능이 자동으로 구현 |
과거에는 JDBC를 사용하여 개발자가 직접 SQL을 작성하고 데이터베이스 연결을 관리해야 했습니다. 하지만 이러한 방식은 코드가 복잡해지고 반복되는 작업이 많다는 단점이 있었습니다.
이러한 문제를 해결하기 위해 ORM 기술이 등장하였고, 자바에서는 ORM의 표준 규격인 JPA가 만들어졌습니다.
JPA는 객체와 데이터베이스 테이블을 자동으로 매핑하여 객체 중심의 개발을 가능하게 하였고, 최근에는 JPA를 더욱 편리하게 사용할 수 있도록 Spring Data JPA가 널리 사용되고 있습니다.
실제 동작 구조는 개발자가 Spring Data JPA를 사용하여 데이터를 요청하면 내부적으로 JPA가 동작하고, JPA 구현체인 Hibernate가 SQL을 생성한 뒤 JDBC를 통해 데이터베이스에 접근하게 됩니다.
Spring → Spring Data JPA → JPA → Hibernate → JDBC → Database
스프링 테스팅(Spring Testing)
소프트웨어 개발에서 테스트는 매우 중요한 요소입니다. 스프링은 애플리케이션 테스트를 쉽게 작성할 수 있도록 Spring Testing 모듈을 제공합니다. 이 모듈을 사용하면 단위 테스트(Unit Test)와 통합 테스트(Integration Test)를 작성할 수 있습니다.
| 테스트 명칭 | 의미 | 예시 |
| 단위 테스트 (Unit Test) |
특정 메서드나 클래스가 의도한 대로 동작하는지 독립적으로 검증 |
계산 로직, 예외 처리 검증 등 |
| 통합 테스트 (Integration Test) |
여러 모듈이 함께 동작할 때 문제가 없는지 검증 | DB 연동, 외부 API 호출 등 실제 환경과 유사한 조건에서 테스트 진행 |
테스트가 중요한 이유는 단순히 버그를 찾는 것에 그치지 않고, 코드를 수정했을 때 기존 기능이 망가지지 않았는지 빠르게 확인할 수 있습니다. 프로젝트 규모가 커질수록 테스트의 중요성은 더욱 커져, 테스트는 가능한 자동화 하여 관리하는 것이 권장됩니다.
Spring Boot (스프링 부트)
기존 스프링 프레임워크는 프로젝트를 시작할 때 XML 및 라이브러리 설정 등 초기 설정이 매우 복잡하다는 단점이 있었습니다. 이러한 문제를 해결하기 위해 등장한 것이 스프링 부트입니다.
스프링 부트는 '구성보다 관례(Convention over Configuration)' 개념을 도입하여, 일반적으로 많이 사용하는 설정을 자동으로 구성해 줍니다. 따라서 개발자는 기본 설정을 직접 작성할 필요 없이, 개발자가 필요한 부분만 설정하여 변경하면 됩니다.
* Ex) 스프링 부트는 내장 톰캣(Embedded Tomcat)을 제공하여 별도의 서버 설치 없이 애플리케이션을 실행할 수 있습니다.
'Spring' 카테고리의 다른 글
| [Spring Boot] 테스트의 이해와 @Transactional 동작 원리 (0) | 2026.05.12 |
|---|---|
| [Spring] - AOP(관점 지향 프로그래밍)의 이해 (0) | 2026.04.28 |
| [Spring] - BCryptPasswordEncoder를 이용한 비밀번호 암호화와 보안 원리 (1) | 2026.04.16 |
| [Spring] 싱글톤 패턴과 싱글톤 컨테이너 정리 (0) | 2026.03.23 |
| [Spring] 스프링 프레임워크의 기초 이해(2) - 스프링 애플리케이션 구조와 스프링 컨테이너, 빈(Bean) (0) | 2026.03.15 |
