스프링 부트 핵심 가이드를 읽고 정리한 내용이다.
이번 파트(part 01, 02, 03)는 개발에 들어가기 전에 알아야 할 지식에 대한 전반적인 설명이다.
스프링 프레임워크
스프링 프레임워크(Spring Framework)는 자바 기반의 엔터프라이즈급 애플리케이션을 개발하기 위한 다양한 기능을 제공하는 프레임워크이다. (*엔터프라이즈급 개발 : 대규모 데이터를 처리하는 환경을 대상으로 하는 애플리케이션 개발)
자바 기반 프레임워크 중 부동의 1위인 스프링의 핵심 가치는 이러하다.
"애플리케이션 개발에 필요한 기반을 제공해서 개발자가 비즈니스 로직 구현에만 집중할 수 있게끔 하는 것"
처음 스프링을 접할 땐 이해하지 못하고, 개발을 도와주는 프레임워크면 당연한거 아닌가? 라고 생각했던 시절도 있었다. 하지만.. Spring Framework 없이 Servlet만으로 개발을 해보면서 무슨 말인지 조금은 깨달을 수 있었다.
이제 스프링의 구조와 특징을 알아보자.
제어의 역전 (IoC; Inversion of Control)
보통은 객체를 생성하고 관리하는 일을 개발자가 직접 한다.
아주 쉬운 예시로 이런 객체 생성 말이다.
Book book = new Book();
제어의 역전이란 이러한 역할이 뒤바뀐 것이다.
우리는 객체의 생성 및 관리를 프레임워크에게 맡기고, 객체의 생명 주기를 프레임워크(스프링 컨테이너)가 알아서 관리한다.
이를 통해서 의존성 주입(DI), AOP 등이 가능해졌다.
의존성 주입(DI; Dependency Injection)
의존성 주입이랑 제어의 역전의 방법 중 하나로, 사용할 객체를 직접 생성하지 않고 스프링 컨테이너가 생성한 객체를 주입받아 사용하는 방식을 의미한다.
의존성을 주입 받는 방법은 세가지가 있다.
1. 생성자를 통한 의존성 주입
@Service
public class ItemService {
private final ItemRepository itemRepository;
@Autowired // 생성자가 하나이면 @Autowired를 생략할 수 있다.
public ItemService(ItemRepository itemRepository) {
this.itemRepository = itemRepository;
}
}
스프링의 컴포넌트 스캔을 통해 생성된 Bean 중 ItemRepository를 찾아서 생성자를 통해 자동으로 주입해주는 방식이다.
스프링에서 권장하는 의존성 주입 방식이며, 다른 방식과는 다르게 이 방식은 final로 선언할 수 있으며, 레퍼런스 객체(의존하는 객체) 없이는 객체를 초기화할 수 없게 설계할 수 있다는 장점이 있다.
2. 필드 객체 선언을 통한 의존성 주입
@Service
public class ItemService {
@Autowired
private ItemRepository itemRepository;
...
}
이전에 많이 사용했다. 의존 객체를 클래스의 필드로 작성하고 이 필드에 스프링이 빈을 바로 꽂아주는 방식이다.
3. setter 메서드를 통한 의존성 주입
@Service
public class ItemService {
private ItemRepository itemRepository;
@Autowired
public void setItemRepository(ItemRepository itemRepository) {
this.itemRepository = itemRepository;
}
}
Setter를 통해 주입하는 방식이다.
관점 지향 프로그래밍 (AOP; Aspect Oriented Programming)
AOP는 스프링의 꽃이라고 표현한다. 그만큼 중요하고, 주요 기술들이 AOP를 통해 구현되어 있다.
객체 지향 프로그래밍(OOP)를 보완하는 수단으로, 공통 관심사(Aspect)를 모듈화하여 주요 비즈니스 로직을 해치지 않고 분리할 수 있다. 이를 통해 단일 책임 원칙을 지킬 수 있으며, 확장성이 증가된다.
여기서 비즈니스 로직은 '핵심 기능'을 말하고, 공통 관심사 라는 것은 각 메서드 또는 클래스에서 공통적으로 처리되어야 하는 '부가 기능'을 말한다.
즉, AOP의 목적은 OOP와 마찬가지로 모듈화해서 재사용 가능한 구성을 만드는 것이고, 모듈화된 객체를 편하게 적용할 수 있게 함으로써 개발자가 비즈니스 로직을 구현하는데만 집중할 수 있게 도와주는 것이다.
스프링 프레임워크에는 다양한 모듈들이 있는데, 그 중 스프링 부트에 대해 살펴 볼 것이다.
스프링 부트
스프링 부트는 스프링 프레임워크를 더욱 편리하게 사용할 수 있도록 해준다.
- 의존성 관리
- 스프링 프레임워크에서는 개발에 필요한 각 모듈의 의존성을 직접 설정해야 했고, 호환되는 버전을 명확히 명시해야 했다.
- 스프링 부트에서는 ‘spring-boot-starter’라는 의존성을 제공하여 위와같은 불편함을 해소해준다. 자주 사용되고 서로 호환되는 모듈 조합을 제공해준다.
- 자동 설정
- 스프링 부트는 스프링 프레임워크의 기능을 사용하기 위한 자동 설정을 지원한다.
- @SpringBootApplication
- 내장 WAS
- 스프링 부트의 각 웹 애플리케이션에는 내장 WAS가 존재한다.
- spring-boot-starter-web 안에 해당 스프링 버전에 맞는 tomcat을 내장하고 있다.
- 모니터링
- 서비스를 운영하는 시기에는 해당 시스템이 사용하는 스레드, 메모리, 세션등 주요 요소들을 모니터링해한다. 스프링 부트에는 Spring boot Actuator라는 자체 모니터링 도구가 있다.
스프링 부트 동작 방식
클라이언트에게 요청을 받으면
- DispatcherServlet이 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회한다.
- 핸들러를 실행할 수 있는 핸들러 어댑터를 조회한다.
- 핸들러 어댑터를 실행하여 핸들러(컨트롤러)를 실행한다.
- 핸들러 어댑터는 핸들러(컨트롤러)가 반환하는 정보를 ModelAndView로 변환하여 반환한다.
- 뷰 리졸버를 찾고 실행한다.
- 뷰 리졸버는 뷰 객체를 반환한다.
- 뷰를 통해 뷰를 렌더링한다.
레이어드 아키텍처
애플리케이션의 컴포넌트를 유사 관심사를 기준으로 레이어로 묶어 수평적으로 구성한 구조를 의미한다.
- 프레젠테이션 계층
- 애플리케이션의 최상단 계층으로 클라이언트의 요청을 해석하고 응답하는 역할을 한다.
- 별도의 비즈니스 로직을 포함하고 있지 않으므로 비즈니스 계층으로 요청을 위임하고 받은 결과를 응답하는 역할만 수행한다.
- 비즈니스 계층
- 애플리케이션이 제공하는 기능을 정의하고 세부 작업을 수행하는 도메인 객체를 통해 업무를 위임하는 역할을 수행한다.
- DDD(Domain-Driven Design) 기반의 아키텍처에서는 비즈니스 로직에 도메인이 포함되기도 하고, 별도로 도메인 계층을 두기도 한다.
- 데이터 접근 계층
- 데이터베이스에 접근하는 일련의 작업을 수행한다.
REST API
- REST란?
- 서버에서 마치 함수를 호출하듯이 결과를 가져올 수도 있다는 의미로 REST라고 얘기한다.
- HTTP URI를 통해 자원을 명시하고, HTTP Method를 통해 자원에 대한 CRUD Operation을 적용한다.
- REST API란?
- API는 Application Programming Interface의 약자로, 애플리케이션에서 제공하는 인터페이스를 의미한다.
- REST API는 REST를 기반으로 애플리케이션 서비스 API를 구현한 것을 말한다.
- REST 아키텍처를 구현하는 웹 서비스를 ‘RESTful하다’ 라고 표현한다.
이상으로 Part 01 ~ 03에 대한 핵심만 간략하게 정리한 내용이다.
'spring & java' 카테고리의 다른 글
[Spring] SSE + Redis pub/sub (1) | 2024.01.18 |
---|---|
[Spring] 스프링 부트 핵심 가이드 - API 작성 기초 (4) | 2023.10.29 |
[Spring] Spring AOP 적용 (0) | 2023.06.19 |
[Java] 비동기 + multi threading 구현 (0) | 2023.03.01 |
[Spring] Spring Security + JWT (7) | 2023.02.06 |