1. 학습내용
16:00 ~ 17:00 스탠다드반 (Spring MVC) ( 박성규, 김재연 튜터님 )
# 공통적으로 스탠다드반에서 , 스프링 입문강의에서 MVC를 다뤄서 스탠다드반 만 다룸.
프레임워크 VS 라이브러리는 이전 포스팅에 정리해놓은 것이 있다.
2025.03.08 - [CS/SW공학] - 라이브러리 VS 프레임워크
라이브러리 VS 프레임워크
IT 개발 업무 쪽으로 공부하다보면 어디서 많이 들어보던말이 있을 것이다. 오늘은 라이브러리 와 프레임워크 에 대해서 알아보고자 포스팅 할 예정이다. 필자는 이해하기 쉽게 라이브러리와
dimenshun.tistory.com
어노테이션
어노테이션은 특정 코드를 사용하는 프로그램에게 정보를 전달하는 것이다.
- 정의
- 어노테이션은 @ 기호로 시작하며, 클래스, 메서드, 변수, 매개변수, 패키지 등에 추가할 수 있다.
- 내장 어노테이션
- @Override
- 메서드가 상위 클래스나 인터페이스의 메서드를 오버라이드하고 있음을 나타낸다.
- 이때 컴파일러는 메서드가 실제로 오버라이드하고 있는지 확인한다. ( 컴파일러는 인지 ★ )
- 메서드가 상위 클래스나 인터페이스의 메서드를 오버라이드하고 있음을 나타낸다.
- @Deprecated
- 해당 요소가 더 이상 사용되지 않음을 나타낸다.
- 해당 어노테이션이 붙은 코드를 사용하면 컴파일 경고가 발생한다.
- @SuppressWarnings
- 컴파일러 경고를 억제한다.
- 사용되지 않는 변수에 대한 경고를 무시할 수 있다.
- 컴파일러 경고를 억제한다.
- @Override
- 사용자 정의 어노테이션
- 개발자가 필요에 따라 직접 어노테이션을 정의할 수 있다.
- 사용자 정의 어노테이션은 특정 메타데이터를 추가하거나,
- AOP(Aspect-Oriented Programming) 같은 기술과 결합하여 다양한 기능을 구현할 수 있다.
Lombok
📚 보일러 플레이트 코드를 줄여주는 라이브러리로 자동으로 보일러 플레이트 코드를 생성하여
코드의 가독성과 유지보수성을 높여준다. Lombok은 어노테이션 기반으로 동작하며,
주로 컴파일 시점에 소스 코드를 변환하여 필요한 메서드를 자동으로 생성한다.
❓ 보일러 플레이트 코드(Boilerplate code)란? getter/setter 메서드, 생성자, toString 메서드 등과 같이 반복적으로 작성되는 코드를 뜻함.
- 주요 Lombok Annotation
- @Getter, @Setter
- 클래스의 모든 필드에 대한 getter와 setter 메서드를 자동으로 생성한다.
- @ToString
- 객체의 toString() 메서드를 자동으로 생성한다.
- 기본적으로 클래스의 모든 필드를 포함하며, 특정 필드를 제외하거나 포맷을 지정할 수도 있다.
- @EqualsAndHashCode
- equals()와 hashCode() 메서드를 자동으로 생성한다.
- 객체의 동일성과 해시 코드를 정의하는데 사용된다.
- @NoArgsConstructor, @AllArgsConstructor, @RequiredArgsConstructor
- 기본 생성자를 생성한다.
- 모든 필드를 매개변수로 하는 생성자를 생성한다.
- 필수(final) 필드만을 매개변수로 하는 생성자를 자동으로 생성한다.
- @Data
- @Getter, @Setter, @ToString, @EqualsAndHashCode,@RequiredArgsConstructor를 한꺼번에 적용하는 어노테이션이다.
- 주로 테스트 용도로 사용한다.
- @Slf4j
- 클래스에 로그를 남기기 위한 Logger 객체를 자동으로 생성한다.
- @Builder
- 빌더 패턴을 적용해 객체를 생성할 수 있게 합니다. 복잡한 객체 생성에 유용하며, 필드 이름을 명시적으로 지정하면서 객체를 생성할 수 있다.
- @Getter, @Setter
@Builder
public class User {
private String name;
private int age;
}
User user = User.builder()
.name("John")
.age(30)
.build();
Spring Framework
- Spring Framework 등장 배경
- 대형 쇼핑몰 시스템(엔터프라이즈 애플리케이션)
- 수백만 명의 고객이 동시에 상품을 검색하고, 장바구니에 담고, 결제를 시도한다.
- 이러한 시스템은 많은 사용자의 요청을 한꺼번에 처리해야 한다.
- 서버의 성능, 신뢰성, 보안이 아주 중요하다.
- 하지만 이러한 요소들을 모두 고려하면서 비즈니스 로직을 개발하는 것은 쉽지 않다.
- 만약 누군가가 이러한 복잡한 부분을 해결해 주는 개발 환경을 제공해준다면, 개발자는 비즈니스 로직에만 집중할 수 있게 된다.
- 이때 등장한 것이 바로 Spring Framework 이다.
- Spring Framework는 서버 성능, 안정성, 보안 문제를 고도화된 수준으로 해결해준다.
- 개발자들은 복잡한 문제를 해결하는 대신, 비즈니스 로직 개발에 집중할 수 있게 되었다.
- 대형 쇼핑몰 시스템(엔터프라이즈 애플리케이션)
- Spring Framework 특징
- 애플리케이션의 다양한 구성 요소를 유연하게 연결하고 관리할 수 있도록 해준다.
- Spring Framework는 누구나 사용할 수 있는 오픈소스 이다.
- 모듈화되어 있어 필요에 따라 특정 기능만 선택적으로 사용할 수 있다.
- Java언어의 가장 큰 특징인 객체 지향 언어의 특징을 살려낸 프레임워크이다.
- 캡슐화
- 상속
- 추상화
- 다형성
- Spring Framework로 만드는 Web Application

- Web Application 이라는 라면을 끓인다(만든다).
- 라면 : Java
- 냄비 : Spring
Spring boot
Spring Framework를 기반으로 하여 간편하고 신속하게 애플리케이션을 개발할 수 있도록 도와주는 도구
- Spring Boot의 등장 배경
- 스프링 프레임워크는 초기 설정과 구성 파일이 복잡하고 방대했다.
- 스프링 애플리케이션을 개발하고 배포하기 위해서는 여러 가지 의존성 관리와 서버 설정이 필요하다.
- 최소한의 노력으로 스프링 애플리케이션을 쉽게 개발하고 배포할 수 있는 방법이 필요했다.
- Spring Boot의 특징
- 자동 구성(Auto-configuration) 기능을 제공하여, 개발자가 복잡한 설정을 직접 처리할 필요 없이 기본 설정으로도 비즈니스 로직에 집중할 수 있게 해준다.
- 내장 WAS(Tomcat)를 제공하여, 애플리케이션을 별도의 서버 설정 없이 바로 실행할 수 있다.
- spring-boot-starter-web를 빌드 관리 도구에 추가하면 웹 애플리케이션에 필요한 모든 종속성과 설정이 자동으로 구성된다.
- 라이브러리들의 버전을 명시하지 않아도 호환 가능한 버전들을 찾아 자동으로 설정해준다.
- 주의! 버전 관련 문제를 100% 해결해 주는 것은 아니다.
- Spring Boot로 만드는 Web Application

- Web Application 이라는 라면을 끓일 때(만들 때) 조리 도구 세트를 사용한다.
- 라면 : Java
- 냄비 : Spring
- 조리 도구 세트 : Spring Boot
빌드 관리 ( Gradle )
Java와 유사한 문법 구조를 가진 Groovy기반의 스크립트 언어를 사용하며 다양한 소프트웨어를 빌드(Build)할 수 있는 유연한 빌드 자동화 도구이다.
- 빌드(Build)
- 소스 코드를 컴퓨터가 실행 가능한 파일로 변환해주는 작업
- 빌드 자동화 도구
- 빌드, 라이브러리 관리, 테스트, 배포 등을 자동화 하여 수행한다.
- Gradle 특징
- 유연성
- 복잡한 빌드 시나리오를 처리할 수 있는 유연한 시스템을 제공한다.
- 빌드 스크립트를 통해 다양한 빌드 작업을 정의하고, 필요한 경우 커스터마이징할 수 있다.
- 성능
- Build Cache
- 빌드 결과물을 캐싱하여 재사용한다.
- 라이브러리 의존성을 캐싱하여 재사용한다.
- 점진적 빌드
- 마지막 빌드 호출 이후 변경된 부분만 빌드한다.
- 변경되지 않은 부분은 캐시 결과를 검색해 재사용한다.
- 데몬 프로세스
- 다음 빌드 작업을 위해 백그라운드에서 대기하는 프로세스
- 초기 빌드 이후부터는 빌드 실행 시 초기화 작업을 거치지 않는다.
- Build Cache
- 멀티 프로젝트 빌드 지원
- 공통으로 사용하는 클래스를 모듈로 만들어 독립적인 각 프로젝트에서 사용할 수 있도록 한다.
- 설정 주입 방식
- 필요한 설정을 직접 프로젝트에 주입하는 방식이다.
- 공통되는 정보는 묶어서 한번에 주입이 가능하다.
- 프로젝트별로 설정을 다르게 주입할 수 있다
- 유연성
build.gradle
Groovy 기반 언어의 빌드 스크립트로 스크립트를 작성하면 코드를 빌드하고, 라이브러리들의 의존성을 관리할 수 있다.
플러그인
- 특정 작업을 위해 모아 놓은 task들의 모음집
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.5'
id 'io.spring.dependency-management' version '1.1.3'
}
의존성 관리
- 프로젝트에서 사용하는 라이브러리나 패키지를 관리한다.
dependencies {
// JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// SECURITY
implementation 'org.springframework.boot:spring-boot-starter-security'
// WEB
implementation 'org.springframework.boot:spring-boot-starter-web'
// LOMBOK
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// MySQL
runtimeOnly 'com.mysql:mysql-connector-j'
// Validation
implementation 'org.springframework.boot:spring-boot-starter-validation'
// JWT
compileOnly group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'
// DEV_TOOL
developmentOnly 'org.springframework.boot:spring-boot-devtools'
// TEST
testRuntimeOnly 'com.h2database:h2'
testCompileOnly 'org.projectlombok:lombok'
testCompileOnly group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
}
- 의존성 설정
- 라이브러리를 추가하는 시점을 설정할 수 있다.
- Implementation
- 컴파일, 런타임 시점 모두에서 사용한다.
- compileOnly
- 컴파일할 때만 사용되고 런타임 때에는 사용하지 않는다.
- runtimeOnly
- 런타임 때만 사용한다.
- testImplementation
- 테스트할 때만 사용한다.
repositories
- 라이브러리가 저장된 위치를 정의하고 저장소에서 라이브러리를 가져옴
repositories {
mavenCentral()
}
JAVA 웹 기술의 역사
- Servlet의 등장 (1997)
- 개요
- Java를 사용한 웹 개발의 시초로, 서버에서 동적으로 콘텐츠를 생성하기 위해 사용되었다. 클라이언트의 요청을 받고, 그에 대한 응답을 생성하는 기본적인 구조를 제공했다.
- 단점
- 코드의 복잡성이 증가하고 유지보수가 어려워졌다.
- 개요
- JSP (JavaServer Pages) 도입 (1999)
- 개요
- JSP는 HTML 내에 Java 코드를 삽입할 수 있는 기술로, 웹 페이지를 더 쉽게 동적으로 생성할 수 있도록 도와주었다.
- 단점
- JSP 내에 비즈니스 로직을 분리할 수 없다.
- 개요
- Servlet, JSP 기반의 MVC 패턴 도입
- 개요
- MVC 패턴이 도입되면서, UI, 비지니스 로직, 데이터를 분리하여 개발하는 방식이 등장했다.
- Servlet은 주로 컨트롤러(비지니스 로직)로 사용되었고, JSP는 뷰(UI)를 담당하게 되었다.
- 장점
- MVC 패턴은 웹 애플리케이션의 유지보수성과 확장성을 크게 향상시켰다.
- 단점
- 개발자가 중복적으로 설정해줘야 하는 부분들이 다수 발생했다.
- 개요
- MVC 프레임워크의 등장과 발전 (2000~2010)
- 개요
- Struts, Spring 등의 MVC 프레임워크가 등장하며, 웹 애플리케이션 개발이 더욱 구조화되고 효율적으로 변했다.
- 그중 Spring MVC는 단순하면서도 강력한 기능을 제공하여, Java 웹 개발의 표준으로 자리 잡게 되었다.
- 중복적으로 설정해야 하는 부분들을 프레임워크로 자동화 했다.
- 단점
- 여전히 애플리케이션 개발 관련 설정이 복잡했다.
- 개요
- Annotation 기반의 Spring MVC(2007~현재)
- 개요
- Annotation을 통해 애플리케이션 설정의 복잡함을 줄여주었다.
- 장점
- 더 직관적이고 간결한 방식으로 웹 애플리케이션을 개발할 수 있게 되었다.
- 개요
- Spring Boot의 등장(2014~현재)
- 개요
- Spring 프레임워크를 보다 쉽게 사용하도록 만든 도구로, 설정과 복잡한 초기 설정 작업을 자동화했다.
- 내장 Tomcat을 가지고 있다.
- 장점
- 개발자들이 빠르게 애플리케이션을 개발할 수 있도록 도와준다.
- 개요
- 최신 기술 동향
- Web Servlet
- Spring MVC
- 안정적이고 동기식 프로그래밍 모델을 기반으로 한 웹 애플리케이션 개발에 널리 사용된다.
- Spring MVC
- Web Reactive
- Spring WebFlux
- 비동기 및 넌블로킹 모델을 기반으로 한 웹 프레임워크로, 높은 동시성을 요구하는 애플리케이션에서 효율적인 성능을 제공한다. 함수형 프로그래밍 스타일을 지원하며, 서블릿 기술 대신 Netty 등의 비동기 서버를 사용한다.
- 서블릿 기술을 사용하지 않으며, 실시간 데이터를 처리하거나 높은 동시성을 요구하는 애플리케이션에 적합하다.
- RDBMS 지원 부족과 높은 기술적 난이도 등으로 인해, 아직은 MVC 모델이 많은 실무에서 더 많이 사용되고 있다.
- Spring WebFlux
- Web Servlet
{ 스탠다드반 }
Spring MVC(model-view-controller) ▶ Spring 프레임워크의 웹 애플리케이션 개발을 위한 모듈로, MVC패턴을 기반으로 클라이언트 요청을 처리하는 구조를 제공.
특징
- 유연한 아키텍처 : 다양한 View 기술(JSP, Thymeleaf, FreeMarker 등)
- 강력한 요청 처리 기능 : DispatcherServlet을 중심으로 요청을 컨트롤러에 매핑
- DI(의존성 주입) 지원 : IoC 컨테이너 기반의 유연한 객체 관리
- 다양한 요청 매핑 기능 : @RequestMapping, @GetMapping, @PostMapping 등을 이용한 URL 매핑 지원
Spring MVC 동작 흐름 ★

- 클라이언트가 HTTP를 요청
- DispatcherServlet이 요청을 수신
- HandlerMapping을 이용해 적절한 컨트롤러 탐색
- 해당 컨트롤러를 실행할 핸들러 어댑터를 조회
- 핸들러(컨트롤러) 실행 후 ModelAndView 반환
- ViewResolver를 이용해 적절한 View 결정
- View 객체를 반환해 DispatcherServlet이 View를 렌더링
- HTML 응답을 클라이언트에게 반환

- @ResponseBody 어노테이션을 사용하면 ViewResolver를 거치지 않고, HTTP 응답 본문에 데이터를 직접 반환합니다.
- DispatcherServlet이 핸들러(컨트롤러)의 반환 값을 받으면, 이를 HttpMessageConverter를 통해 JSON, XML 등의 형식으로 변환합니다.
- RESTful API 개발 시 유용하게 사용됩니다.
@Controller
@RequestMapping("/api")
public class ApiController {
@GetMapping("/message")
@ResponseBody
public String getMessage() {
return "Hello, Spring MVC!";
}
}
위 코드를 실행하면 http://localhost:8080/api/message 요청 시 응답 본문으로 "Hello, Spring MVC!" 가 반환됩니다.
@RestController
@RequestMapping("/api")
public class UserApiController {
@GetMapping("/users")
public List<String> getUsers() {
return Arrays.asList("User1", "User2", "User3");
}
} // 호출시 ["User1", "User2", "User3"] 반환됨
위 코드를 실행하면 http://localhost:8080/api/users 요청 시, JSON 형식으로 데이터가 반환됩니다.
@RestController = @ResponseBody + @Controller 합친것 이라고 봐두면 된다.
주요 컴포넌트 (Layer 관점에서 설명)
All-in-One 컨트롤러의 문제점
초기 개발 단계에서 많은 개발자들은 컨트롤러에서 모든 작업을 수행하는 "All-in-One 컨트롤러"를 구현하는 실수를 저지릅니다. 이러한 접근 방식은 다음과 같은 문제점을 초래함 ( 하나로 모든것을 통제하는 컨트롤러 )
- 높은 결합도: 컨트롤러가 비즈니스 로직과 데이터 액세스를 직접 수행하면, 코드의 재사용성이 떨어지고 유지보수가 어려워짐.
- 확장성 부족: 컨트롤러의 코드가 비대해질수록 기능 추가 및 확장이 어려워짐.
- 테스트 어려움: 컨트롤러에 모든 로직이 포함되어 있으면 단위 테스트가 복잡해지고, 모의(Mock) 객체를 활용한 테스트가 어렵게 됨.
- SRP(Single Responsibility Principle) 위반: 컨트롤러는 요청을 처리하는 역할만 해야 하지만, 비즈니스 로직까지 담당하면 역할이 과도하게 집중됨.
✅ 올바른 예제 (레이어 분리 적용)
// Service Layer
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public List<User> getAllUsers() {
return userRepository.findAll();
}
}
// Controller Layer
@RestController
@RequestMapping("/user")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/list")
public List<User> getUsers() {
return userService.getAllUsers();
}
}
- 컨트롤러는 비즈니스 로직을 직접 수행하지 않고, Service 계층을 호출하여 역할을 분리함
- 유지보수가 쉬워지고, 테스트가 용이해짐
- 확장성이 향상됨 (비즈니스 로직 변경 시 컨트롤러 수정 없이 Service만 변경 가능)

1) 프레젠테이션 레이어 (Presentation Layer)
DispatcherServlet
- 모든 요청을 받아 컨트롤러로 전달하는 프론트 컨트롤러 역할
- HandlerMapping을 이용하여 적절한 컨트롤러를 찾음
Controller (@Controller, @RestController)
- 클라이언트의 요청을 받아 서비스 계층과 상호작용
- @RequestMapping, @GetMapping, @PostMapping 등의 어노테이션을 통해 요청을 매핑
- Model 객체를 이용해 데이터를 View로 전달하거나 JSON 형식으로 반환
ViewResolver
- 컨트롤러에서 반환한 View 이름을 실제 화면(JSP, Thymeleaf 등)으로 변환
- View 엔진을 통해 최종 HTML 응답을 생성
2) 비즈니스 레이어 (Business Layer)
Service (@Service)
- 비즈니스 로직을 처리하는 계층
- 여러 컨트롤러에서 공통적으로 사용하는 로직을 모아두는 역할
- Repository 계층과 상호작용하며 데이터를 가공 후 컨트롤러로 전달
3) 데이터 액세스 레이어 (Data Access Layer)
Repository (DAO, @Repository)
- 데이터베이스와 직접적인 상호작용을 담당
- JPA, MyBatis 등의 ORM 프레임워크와 함께 사용
- 데이터를 조회, 삽입, 수정, 삭제하는 역할을 수행

DTO (Data Transfer Object) 는 데이터를 보내주는 역할을 한다.
@Controller @Service @Bean @Repository 같은 친구들은 기능을 부여해주는 게 아니라 "이런 역할을 하는 녀석이다!" + 해당 어노테이션의 객체라고 본다.
View 기술 (JSP vs Thymeleaf)
Spring MVC에서 사용하는 대표적인 View 기술
| 기술 | 특징 |
| JSP | 전통적인 Java기반의 View, Servlet과 함께 동작 |
| Thymeleaf | HTML 기반의 템플릿 엔진, 최신 Spring과 잘 연동 |
결론
- Spring MVC는 강력하고 유연한 웹 애플리케이션 개발 프레임워크
- 다양한 View 엔진과 연동 가능하며 REST API 구축도 용이
- Spring Boot와 결합하면 더욱 빠르고 효율적인 개발 가능
- 새롭게 알게 된 점
Servlet, JSP
옛날에는 프론트엔드 개발과 백엔드 개발자가 나뉘어져 있지 않다 ( 웹 개발자 )
풀스택 개발자도 프론트엔드와 백엔드 개발자를 합쳐서 최근에 나온 말임.
[직접 어노테이션을 제작]
@interface 은 어노테이션을 사용자가 직접 정의(제작) 할수 있는 명령어다.
- @Target( ElementType.METHOD )
- @Retention(RetentionPolicy.RUNTIME) 두개가 위에 달려있어야 가능함.
Maven Repository 사이트 ( 의존성 모음 웹사이트 )
2. TMI
오늘은 고용센터 건으로 오전에 외출을 하였다. 그래서 급하게 TIL과 강의를 들어서 힘든 하루였다..
3. 내일 학습 할 것: 스프링 입문 ( ~ 5주차 해보는데 까지 ), 알고리즘
'[내일배움캠프-Sparta] > Spring 6기' 카테고리의 다른 글
| TIL 23 [ Spring ( 응답 데이터, 메모장 만들기 실습 ) + 스탠다드반 ( 예외처리 )] (0) | 2025.03.20 |
|---|---|
| TIL 22 [ Spring ( 어노테이션II, Request Mapping, 요청 데이터) ] (0) | 2025.03.19 |
| TIL 20 [ Spring( 네트워크, 용어, HTTP, Rest API ) ] (0) | 2025.03.17 |
| TIL 19 [ Java (스트림) , 미니세션 (클래스,객체) + 키오스크 과제 해설 ] (0) | 2025.03.14 |
| TIL 18 [ 키오스크 과제 (도전🔥 2단계) + Java ( 컬렉션, 스트림 ) ] (0) | 2025.03.13 |