🚀
처음 공부하는 Spring Boot
2025.03.30
엄두가 안 났던 스프링 부트를 공부해보자!! 신난다~ (두근두근)
JVM
자바를 실행하기 위한 가상머신
- JAVA 어플리케이션은 JVM 위에서 동작하기 때문에 OS에 종속적이지 않음
- 스택 기반의 가상 머신으로 클래스 로더, 실행 엔진, Runtime Data Area로 구성되어 있음
- 클래스 로더
.class
파일을 로드하고, jar 파일 내 저장된 클래스를 JVM의 Heap(Metaspace or PermGen)에 탑재하는 역할
- 실행 엔진
- 인터프리터와 JIT(Just In Time)으로 클래스를 실행
- 가비지 컬렉터로 사용하지 않는 메모리를 찾아 삭제
- Runtime Data Area
- 프로그램 수행을 위해 OS에서 할당 받은 메모리 공간 (Thread, Heap, …)
REST란?
Representational State Transfer
- 자원의 이름으로 구분하여 해당 자원의 상태를 주고 받는 모든 것을 의미함
- 클라이언트와 서버 간 데이터를 주고 받는 방식에 대한 아키텍처 스타일
REST 구성 요소
- 자원 : HTTP URI
- 자원에 대한 행위 : HTTP Method
- 자원에 대한 행위의 내용 : HTTP Message Payload
REST의 대표 특징 5가지
- 클라이언트와 서버의 역할을 명확히 분리
- Stateless : 각 요청은 독립적이며, 서버는 클라이언트의 이전 요청 상태를 기억하지 않음
- Cacheable : 응답은 캐시될 수 있어야 하며, 이를 통해 네트워크 비용과 응답 시간을 줄일 수 있어야 함
- 클라이언트와 서버는 통신을 위해 프록시 서버, 로드 밸런서, 게이트웨어 같은 여러 중간 계층을 거칠 수 있음
- 일관된 엔드포인트와 HTTP 메서드를 사용해야함
RESTful API vs REST API
RESTful API
- REST의 철학을 잘 지켜서 만든 API
REST API
- 일반적으로 REST 아키텍처를 따르는 API를 말함
- 다만 엄밀히 말하면 REST의 모든 원칙을 지키지 않아도 REST API라고 부르기도 함
- 무상태성만 지키고 일관된 인터페이스가 없더라도 REST API라고 부르는 경우 있음
웹 서버 vs WAS
웹서버는 정적 콘텐츠 처리, WAS는 동적 로직 처리
같이 사용하면 좋은 이유?
- 웹서버가 정적 리소스를 처리해주면 WAS는 오직 비즈니스 로직에만 집중 가능
- 부하 분산과 보안 처리(Nginx에서 SSL 종료 등)에 유리
- 요청 캐싱, 리버스 프록시, 로드 밸런싱 등도 웹서버가 담당
Spring Boot
Spring Boot 기본 폴더 구조
src/
└── main/
├── java/
│ └── com/yourdomain/projectname/
│ ├── config/
│ ├── controller/
│ ├── service/
│ ├── repository/
│ ├── domain/ (또는 model/)
│ └── ProjectNameApplication.java
└── resources/
├── static/
├── templates/
├── application.properties (또는 application.yml)
└── ...
- config : CORS 설정 또는 WebMvc 설정 등을 담당하는 설정 파일
- controller : 클라이언트 요청을 받아서 처리하고, 응답을 반환하는 계층 (api)
- domain/model : 실제 데이터 모델을 정의
- dto : 클라이언트와 서버 간 요청/응답을 위한 데이터 구조 정의
- repository : 파일 기반 저장소 역할, 데이터베이스에 접근하는 계층
- service : 비즈니스 로직을 담당하는 계층
스프링 어노테이션
스프링 어플리케이션 구성 관련
- @SpringBootApplication : 스프링 부트 애플리케이션의 진입점. 자동 설정, 컴포넌트 스캔 포함
- @Configuration : 설정 클래스를 정의
- @Bean : 개발자가 정의한 스프링 빈 등록
의존성 주입 관련
- @Component : 일반적인 스프링 빈 등록
- @Service : 서비스 계층 정의
- @Repository : 데이터 접근 계층 정의. 예외 변환 기능 포함
- @Autowired : 의존성을 자동으로 주입
컨트롤러 관련
- @RestController : REST API 컨트롤러 정의. @Controller와 @ResponseBody 결합
- @RequestMapping : 요청 URL과 메서드를 매핑
- @GetMapping
- @PostMapping
- @DeleteMapping
- @PathVariable : URL 경로 변수를 매핑
- @RequestParam : URL 쿼리 파라미터를 매핑
- @RequestBody : HTTP Body의 JSON 데이터를 Java 객체로 변환
- @ResponseBody
데이터 관련
- @Entity : JPA 엔티티를 정의
- @Id : 기본 키를 지정
- @GeneratedValue : 기본 키의 자동 생성을 설정
- @Table : 엔터티와 매핑될 테이블 정보 정의
- @Column : 테이블 컬럼에 대한 매핑 정보 정의
- @Transactional : 메서드 또는 클래스의 트랜잭션 관리
Lombok
개발자의 보일러플레이트 코드를 줄이고 가독성을 높일 수 있도록 지원하는 Java 라이브러리
- @Getter
- @Setter
- @Accessors
- @ToString
- @EqualsAndHashCode
- @Data : @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor 포함
- @RequiredArgsConstructor : final 또는 @NonNull 필드만 포함하는 생성자를 자동으로 생성
- @NonNull : 필드 값이 null일 경우 NullPointerException을 발생
- @Value : Data와 비슷하지만 모든 필드를 final로 설정. 불변 객체 생성
- @With
예외 처리하기
1. try-catch
- 작은 범위에서만 처리하고 싶을 때 사용
- 로직이 복잡해지면 난잡해짐
- 모든 API에 대해 동일한 try-catch문을 작성해야 한다는 단점이 있다.
2. @ExceptionalHandler
- 해당 컨트롤러 안에서 발생한 예외만 처리
- 컨트롤러별로 따로 정의해야 함
3. @ControllerAdvice
- 전역 예외 처리
- 모든 컨트롤러에 대해 예외 처리 가능
- 실무에서 가장 많이 사용되는 방식
4. ResponseEntityExceptionHandler
- 스프링 기본적으로 제공하는 예외 처리기를 오버라이딩해서 사용
- 유효성 검증 실패(Validation) 등에 유용
- @ControllerAdvice + @ExceptionHandler 조합은 거의 표준처럼 사용됨
- 예외 응답구조(errorCode, message, timestamp) 등을 DTO로 만들어 통일성 있게 처리하면 좋음
예외 응답 DTO 예시
@Getter
@AllArgsConstructor
public class ErrorResponse {
private String message;
private int status;
private String code;
}
스프링 프레임워크의 개요 및 특징
POJO
상속, 어노테이션, 프레임워크 종속 코드 없는, 순수한 데이터 담는 객체
- Spring Bean은 기본적으로 POJO 기반으로 구성되어, 특정 프레임워크에 종속되지 않도록 POJO 기반 구성 지향
- Spring은 POJO 객체를 IoC 컨테이너에 등록하여 관리하고, 이를 통해 의존성 주입(DI) 및 AOP 기능을 추가
- 사용 예시 : DTO, Entity, Request/Response 객체 등
IoC 컨테이너
제어의 역전(Inversion of Control)을 수행하는 핵심 엔진
- 스프링의 중심
- 객체(Bean)을 생성하고, 주입하고, 관리함
- ApplicationContext가 이 역할을 수행함
Bean
스프링이 관리하는 객체
- @Component, @Service, @Repository, @Controller 등으로 등록됨
- IoC 컨테이너에 의해 자동 생성 & 관리됨
의존성 주입 (DI)
객체 간의 의존 관계를 스프링이 자동으로 주입해주는 것
- 생성자, 세터, 필드를 통해 의존 객체가 자동 주입됨
AOP (관점 지향 프로그래밍)
공통 관심사를 핵심 로직과 분리해서 처리하는 기술
- 로깅, 트랜잭션, 인증, 예외처리 등을 공통적으로 끼워넣을 수 있음
- 핵심 로직을 깔끔하게 유지 가능
스프링 프레임워크의 흐름
- Servlet Container가 실행되면,
- IoC 컨테이너(ApplicationContext)가 동작하고,
- 내부에 있는 빈(Bean)들을 생성하고 등록함
- 필요한 곳에 DI(의존성 주입)으로 연결해주고
- 실행 도중 필요한 공통 처리를 위해 AOP도 함께 동작
Proxy Pattern
Proxy
다른 객체에 대한 접근을 대신 처리해주는 대리인 객체
- 원래 객체를 직접 사용하지 않고, 그 앞에 프록시 객체를 둬서
- 기능을 확장하거나
- 접근을 제어하거나
- 공통 로직을 끼워넣기 위해 사용함
JPA
ORM(Object-Relational Mapping) 구현체,
객체와 관계형 데이터베이스 간의 매핑을 제공하는 표준 인터페이스
- 자바 객체와 DB 테이블을 자동으로 매핑해주는 기술
- SQL을 직접 작성하지 않아도, 자바 코드로 DB 조작 가능
JPA Repository
JPA에서 Repository는 데이터베이스와 직접적인 상호작용을 담당하는 인터페이스
JDBC
Java에서 데이터베이스에 직접 연결해서 SQL을 실행할 수 있도록 해주는 표준 API
- 자바에서 SQL을 직접 작성해서 DB와 통신하는 방식
- JPA 대신해서 정말 가벼운 테스트용으로 씀