스프링 부트의 특징
- stand-alone
- 독립 실행형 스프링 애플리케이션 개발 가능
- 이전에는 WAS를 설치 및 설정하고 개발한 애플리케이션을 WAR 형식으로 패키징하여 WAS에 배포
- 서버에 별도로 WAS를 설치하지 않고도 개발 시작 가능, WAS 관리 등의 작업 부담이 줄어듦
- 내장 서버 지원
- 내장 톰캣과 같은 내장 서버를 라이브러리 형태로 함께 패키징
- 앱 시작 시점에 내장 서버를 초기화 및 실행
- 원하는 환경 어디에서든 독립적으로 실행 가능
- 독립 실행형 스프링 애플리케이션 개발 가능
- opinionated
- 스프링 프레임워크는 자유로운 선택지(라이브러리 등) 제공 -> 빠른 애플리케이션 개발을 방해할 수 있음
- starter: best-practice라고 알려진 라이브러리 조합을 미리 모아둔 것
- 프로젝트 초기 생성 시 의사결정 과정을 생략하고 빠르게 개발을 시작
- spring-boot-starter-web
- 라이브러리 버전 결정, 의존성 버전 관리
- auto-configuration
- 필요한 스프링 빈들을 자동으로 스프링 컨테이너에 등록해주는 기능
- classpath에 존재하는 모든 라이브러리 순회
- 각 라이브러리의 특별한 파일을 읽어옴
- 읽어온 정보를 바탕으로 어떤 설정 클래스를 사용할지 선택
- 이후 설정 클래스의 @Bean이 적용된 메서드를 실행하며, 반환된 객체를 빈으로 등록
- 특별한 파일: AutoConfiguration.imports
- 자동 구성에 사용할 설정 클래스(@Configuration)의 className을 모아둠
- ImportSelector
- 동적으로 설정 파일(@Configuration)을 읽어올 수 있도록 하는 인터페이스
- 구현체는 selectImports() 메서드를 구현해야 함 -> 설정 클래스들의 className을 담은 배열 반환
- 자동 구성을 위한 AutoConfigurationImportSelector를 제공
- spring-boot-autoconfigure
- 자주 사용하는 라이브러리의 경우 자동 구성 설정 클래스르 제공
- jackson, jdbc 등
- 필요한 스프링 빈들을 자동으로 스프링 컨테이너에 등록해주는 기능
스프링 프레임워크
- 자바 기반의 어플리케이션을 만들 수 있다.
- 개발자들은 비즈니스 로직에 집중할 수 있다.
- 이전 EJB라는 프레임워크가 존재
- 목적: 비즈니스 로직과 앤터프라이즈 기술의 분리
- 실제: 너무 비싸고 EJB에 의존적이고 종속적
- 문제점: 스프링 생태계와 기능이 커짐. 외부 라이브러리를 함께 사용할 일이 많아짐 -> 초반 설정에 많은 시간이 필요
- Spring Boot의 등장
스프링 빈
- 스프링 빈: 스프링 IoC 컨테이너가 관리하는 객체
- 스프링 IoC 컨테이너: 빈을 관리하는 객체
왜 스프링 빈의 필요할까?
- 빈과 의존성 주입: 의존성 주입이 필요한 객체를 빈으로 등록하여 스프링 부트가 자동으로 주입해줌
- 빈과 싱글턴
- 싱글턴의 단점: 생성자의 접근제어자를 private으로 설정해 다형성을 적용하기 어려움, 단위 테스트가 어려움
- 스프링 빈이 필요한 이유: 스프링 IoC 컨테이너가 특정 객체의 라이프사이클을 관리한다는 것을 명시
스프링 IoC 컨테이너는 어떻게 빈을 관리할까?
- 빈을 관리하는 방법: 객체 생성 + property 설정 -> 의존 설정 -> 초기화 -> 사용 -> 소멸
- Configuration Metadata(XML, Annotation, Java Config)를 사용해 Bean Definition을 생성
- Bean Definition과 Plain Old Java Objects로 빈 객체를 생성
- 스프링 IoC 컨테이너는 Singleton Registry(key-value 형태로 저장)를 가짐
- 싱클톤인 객체인 빈의 이름을 key로, 객체를 value로 사용
- 동일한 객체를 반환하여 싱글톤 객체로 사용
- 스프링 IoC 컨테이너는 왜 빈을 관리할까?
- 의존성을 사용하는 로직에만 집중 가능
- 의존성 주입될 객체가 동일한 싱글 오브젝트임을 보장
빈 설정 시 주의점
- 여러 메서드가 상태를 변경 시킬 수 있으므로 빈 스코프가 싱글톤인 경우 상태를 가지면 안됨
- 빈 스코프가 @Scope("prototype")인 경우 요청이 올 때마다 생성되기 때문에 상태를 가질 수 있음
- 자동 주입할 인터페이스의 구현체가 2개 이상이라면 충돌 발생
- @Primary : 우선 순위 설정하여 자동 주입하도록 함
- @Qualifier("구현체 이름") : 특정 구현체를 주입하도록 설정 가능
- @Component의 경우 @Configuration과 달리 프록시 처리를 하지 않아 싱글톤을 보장하지 않음
Servlet
- 웹 서버 : 정적 페이지 제공
- WAS : 로직을 수행해서 동적 컨텐츠 생성
- Servlet: 동적 컨텐츠를 만드는데 사용되는 자바 기반의 웹 어플리케이션 프로그래밍 기술 혹은 사용되는 객체
- service() 메서드로 ServletRequest를 비즈니스 로직으로 처리해 ServletResponse로 응답
- Sevlet <- GenericServlet <- HttpServlet : 표준 프로토콜인 Http 요청과 응답을 다룸
- doGet(), doPost(), doPut() 메서드를 가짐
- 필요한 Servlet을 HttpServlet을 상속받아 직접 구현
- WAS에서 Servlet이 실행되는 방법
- 초기: web.xml에서 url-pattern에 해당하는 servlet을 매핑해둠
- Sevlet 3.0 버전 이후로는 어노테이션으로 간단하게 등록 가능
@WebServlet(name = "cartServlet", urlPatterns = "/cart")
public class CartServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
// ...
}
- Servlet을 이용한 웹 요청과 응답 과정
- Servlet 기술을 지원하는 WAS의 경우 - Servlet 실행 환경을 제공
- 클라이언트가 요청을 보내면 웹 서버가 WAS에 요청을 위임하면 수행 후 응답
- 문제점: 화면 레더링 코드의 가독성과 유지보수성이 낮음
- JSP: HTML 코드에 Java 코드를 넣어 동적 웹 페이지를 생성하는 서버 사이드 템플릿 엔진
MVC Model
- MVC Model 1의 한계: JSP의 비즈니스 로직과 HTML 코드 분리 x
- MVC Model 2
- View: 화면을 그리는 일을 수행
- -> Controller: HTTP 요청을 받고 비즈니스 로직을 수행
- <-> Model: 데이터와 비즈니스 로직을 담당
Spring MVC
- 중앙에 있는 DispatcherServlet이 요청을 처리하기 위한 공유 알고리즘을 제공하는 프론트 컨트롤러 패턴을 중심으로 설계됨
- = Spring에서 MVC 디자인 패턴을 적용하여 HTTP 요청을 효율적으로 처리
- DispatcherServlet과 Front Controller
- 모든 API 요청에 무수히 많은 Servlet 클래스를 구현해야 함
- Spring은 DispatcherServlet을 사용해 효율적으로 API 처리
- HTTP 요청이 들어오면 DispatcherServlet이 요청을 분석
- Handler mapping을 통해 Controller를 찾아 요청을 전달
- HandlerAdaptor는 핸들러의 종류에 관계 없이 핸들러(컨트롤러)를 실행
- Controller 처리 완료 후 결과인 데이터(Model)와 View 정보를 전달
- ViewResolver를 통해 View에 Model을 적용하여 클라이언트에게 응답
직렬화와 역직렬화
html 파일이 아닌 JSON 데이터를 반환하고 싶은 경우 @ResponseBody를 추가
Spring에서 자동으로 Java 객체를 JSON으로 변환
- 직렬화: 객체를 바이트 스트림(Json 등)으로 변환하는 과정
- 역직렬화: 직렬화된 바이트 스트림(Json 등)을 객체로 변환하는 과정
- Reflection API: 구체적인 클래스 타입을 알지 못해도 그 클래스의 정보에 접근할 수 있게 해주는 자바 API
Spring Framework 직렬화 과정
- HttpMessageConverter가 수행
- 요청 - canRead, 응답 - canWrite : 클래스 타입을 지원하는지, Media Type을 지원하는지 확인
- ObjectXXXX을 사용 -> Jackson 라이브러리에서 가져옴
Jackson 라이브러리
- Spring 3.0 이후로 Jackson 관련 API를 제공, SpringBoot의 starter-web에서 제공
- 직접 JSON 데이터를 처리해야 할 때 Jackson 라이브러리의 ObjectMapper 사용 가능
- Jackson 라이브러리
- Object <-> JSON 타입의 String으로 변환 가능
- Reflection API를 활용하여 클래스 정보를 동적으로 읽어 직렬화/역직렬화
- 직렬화 방법
- 필드의 접근 제어자를 public으로 한다.
- private 필드에 대해서는 표준 getter를 선언한다. -> getXxxx();
- objectMapper의 writeValueAsString 메서드를 사용해 변환 가능
- 역직렬화 방법
- 표준 Setter/Getter / 기본 생성자 / 생성자 1개 존재하면 역직렬화 가능
- objectmapper의 readValue 메서드를 사용해 변환 가능
- 표준 Setter/Getter / 기본 생성자 / 생성자 1개 존재하면 역직렬화 가능
알면 유용한 Annotation
- @JsonIgnore: 직렬화/역직렬화에서 특정 필드를 제외 가능
- @JsonCreator: 역직렬화 시 생성자, 팩토리 메소드 선택 방법 결정 가능
- @JsonProperty: Json 필드와 객체 필드 이름이나 순서를 다르게 하고 싶을 때
- @JsonFormat: Json 응답의 날짜/시간 형식 지정 가능, 타임존 지정 가능
더보기
출처
https://www.youtube.com/watch?v=XRyt-2BOkAI&list=PLgXGHBqgT2TvpJ_p9L_yZKPifgdBOzdVH&index=26
https://www.youtube.com/watch?v=3gmOuUWPZV4&list=PLgXGHBqgT2TvpJ_p9L_yZKPifgdBOzdVH&index=201
https://www.youtube.com/watch?v=UcpLNgko8lg&list=PLgXGHBqgT2TvpJ_p9L_yZKPifgdBOzdVH&index=209
https://www.youtube.com/watch?v=o5rspNdJ-fE&list=PLgXGHBqgT2TvpJ_p9L_yZKPifgdBOzdVH&index=77
스파르타내일배움캠프 Spring 학습자료
'Spring & JPA' 카테고리의 다른 글
[테코톡] SOLID + 추가 정리 (0) | 2025.04.10 |
---|---|
[테코톡] Lock & JPA Lock (0) | 2025.04.05 |
[테코톡] JPA 연관관계 최적화 (0) | 2025.04.03 |
[테코톡] API 중복 호출 해결기 (0) | 2025.04.02 |
고급 매핑 - 3. 복합 키와 식별 관계 매핑 (0) | 2025.03.19 |