Spring에서 ApplicationContext란 무엇인가?
ApplicationContext는 Spring 프레임워크의 IoC Container에서 Bean의 생성, 와이어링, Bean의 구성
그리고 Bean과 객체들의 life Cycle을 관리하는 역할을 한다.
Spring Bean 과 Servlet 각각 싱글톤으로 관리 된다고 하는데, 왜 그런지 상세히 설명하라
1. 대규모 엔터프라이즈 서버 환경은 서버 하나당 최대 초당 수십, 수백 씩 요청을 받는다.
2. Spring MVC 구조는 요청에 대한 응답을 만들기까지 다양한 객체들이 참여하는 계층구조
그렇기에 요청이 올 때마다 각 로직의 객체를 새로 만든다면 서버의 부하가 심각
➡️ 제한된 객체를 만들도록 싱글턴 사용 권장
➡️ IoC방식 중 DI 컨테이너를 사용해 제어권 컨테이너에게 넘겨 싱글톤 방식 관리.
제어 역전(IoC, Inversion of Control)과
의존성 주입(DI, Dependancy Injection)을 상세히 설명하라
제어 역전 : 객체의 생성은 개발자가 코딩 내 직접 선택하는데, 개발자가 new를 통해 사용하는 것이 아닌
특정 주체가 객체의 생성과 의존성 관리를 진행하는 것
의존성 주입 : 객체가 필요한 의존성이 런타임 시점에 정해지는 것을 의존성 주입이라고 한다.
Spring에서 의존성 주입이란 IoC 컨테이너가 개발자 대신 Bean을 주입한다.
Spring Bean 주입 방법 중 생성자 주입, 필드 주입, 수정자 주입 각각의 장단점에 대해 간략하게 설명하라
생성자 주입 : Spring 공식 Docs에서 추천하는 방식으로, 싱글톤 객체로 등록 후
이를 사용할 의존성이 필요한 component에서 필드 설정 및 생성자를 통해 주입
장점 : 순환참조 방지 가능, final 적용으로 객체의 불변성 보장, NPE 가능성 저하,
컴파일 타임에 의존성 문제를 파악 가능.
필드 주입 : 싱글톤 객체 등록 후 의존성이 필요한 component에서
해당 필드에 @Autowired 어노테이션을 붙인다.
장점 : 직관적
단점 : 테스트가 어렵다.
수정자(Setter) 주입 : 마찬가지로 bean을 설정하고 setter 메서드에 @Autowired 붙여서 사용한다.
장점 : 객체 생성 시점과 의존성 주입 시점을 분리 가능.
+ 필요한 의존성만 주입가능.
단점 : final을 통한 객체의 불변성 보장 불가
@PathVariable, @RequestParam, @RequestBody 각각 어떤 역할을 하는지 설명하라
API 호출을 받을 때 요청으로부터 parameter를 받기 위한 방식이다.
PathVariable은 route로 정의된 인자를 매핑시 사용한다.
RequestParam은 쿼리파라미터로 정의된 인자를 매핑할 때 사용
RequestBody는 HTTP 요청의 본문이 JSON형태로 요청이 들어왔을 때,
이를 사전에 정해둔 DTO 객체로 매핑한다.
@PathVariable, @RequestParam, @RequestBody 어노테이션의 상세 옵션들을 아는대로 설명하라
@PathVariable
name : pathvariable로 등록할 값, value와 같은 옵션이다. 그러므로 둘 다 사용할 경우 그 두개는 같아야함.
required : 필수로 값이 있어야 할 경우에 등록.
@RequestParam
defaultValue : 기본값. 없을 경우 fallback으로 쓰임
name, value, required 위와 동일
@RequestBody
required
@ModelAttribute 은 무엇이며, 어떤 장점을 갖는가?
다수의 파라미터를 쿼리형태로 받을 때 사용한다.
모든 쿼리 파라미터에 대해 각각의 @RequestParam을 사용할 수도 있지만,
ModelAttribute와 DTO의 조합으로 사용할 수 있다.
그런데 ModelAttribute 사용시에는 @NoArgsConstructor와 @Setter의 조합을 추천한다.
그리고 기본값을 설정해 어떤 값이 들어가지 않는 경우 세터로 조율하는 방식이 매우 효과적이다.
Spring 에서 자주 사용되는 @Valid, @Validated 각각 어떤것인지, 어떻게 사용하는지 설명하라
HTTP 요청으로부터 파라미터를 받을 때, 해당하는 값의 validation을 진행하기 위해서 사용하는 어노테이션 입니다.
@Valid는 controller에서 사용하는 validation방법으로, 메서드 단위의 validaiton을 진행한다.
Bean Validation의 표준이다.
DTO나 받은 파라미터에 원하는 valiation방법을 어노테이션을 통해 지정하고, 해당 controller의 method에서 @Valid를 통해 요청 입력파라미터에 대한 검증을 진행한다.
단, 이를 처리하는 주체는 ArgumentResolver이다. MethodArgumentNotValidException 이 발생.
@Validated는 class 그룹 단위의 Validation을 진행한다.
해당 조건이 적용될 그룹을 groups로 지정가능.
AOP 기반 메서드 요청을 인터셉터하여 처리. 그래서 클래스 레벨에 @Validated 선언하면 AOP의 어드바이스 혹은 인터셉터가 등록됨. ConstraintViolationException 이 발생
@JsonInclude 는 무엇을 위해 사용하는지 설명하라
응답 객체가 null 일 경우 JSON 프로퍼티로 표현할지를 결정한다.
응답으로 노출 될 값들에 대한 세부 조율이 가능하다.
필드 단위가 아니라 class 단위로도 적용이 가능하다.
Spring 에 비해 Spring Boot 는 어떤 장점을 갖는지 풀어 설명하여라
Spring이 Servlet, Spring IoC Container 기반 applicationContext를 통해
bean과 의존성 주입 등 웹서버를 제작하기 위한 기능적 토대를 제공한다.
이를 사용자가 직접 설정해주어야 하고, 구축해야 한다.
즉, 구축을 위해서는 추가적인 Tomcat이 필요하다.
이에 비해 Spring Boot는 내장 Servlet Container인 Tomcat을 제공한다.
그렇기 때문에 자동으로 설정이 되어있는 상태에서 의존성 관리까지 제공해준다.
Spring 과 Spring Boot 의 차이에 대해 간략하게 핵심들만 나열하라
Spring은 MVC패턴을 기반으로 한 어플리케이션의 설계에 중점을,
Spring Boot는 웹 어플리케이션과 자바를 기반으로 한 WAS의 설계에 중점을 둔다.
이에 따라 빌드 생성물이 WAR와 JAR로 다르고
서버를 실행하기 위해서 추가적인 톰캣의 필요 유무가 다르다.
자바 어플리케이션 컴파일 결과인 WAR 와 JAR 의 차이에 대해 설명하라
빌드 생성물 : WAR(Web Application Archive) vs JAR(Java Archive)
전자는 웹 애플리케이션 포맷이기에 WAR을 구동할 별도의 외장 서버가 필요하다.
후자는 JRE(JVM)으로 바로 실행 가능한 자바 어플리케이션이다.
즉, JRE(JVM) 만 있으면 바로 실행 가능한 자바 어플리케이션 압축 포맷이다.
전자는 외장 톰캣이 필요하고 후자는 톰캣이 내장되어 있다.
Spring 이 유저로부터 요청을 받고, 응답을 반환하기까지의 모든 과정을 상세하게 설명하라 (Servlet Container와 Spring Container의 관점에서)
- 클라이언트 요청 및 Connection Queue:
- 서블릿 컨테이너 관할: 클라이언트의 HTTP 요청이 들어오면 서블릿 컨테이너(예: Tomcat)는 요청을 수신하고 Connection Queue에 저장합니다.
- HttpServletRequest 객체: 서블릿 컨테이너는 HTTP 요청을 HttpServletRequest 객체로 변환하여, 서블릿 컨테이너가 관리하는 HTTP 프로토콜 기반의 요청 객체로 매핑합니다.
- DispatcherServlet에 할당 및 스레드풀 사용:
- 서블릿 컨테이너에서 스프링 컨테이너로: DispatcherServlet은 서블릿 컨테이너에서 초기화되며, 모든 HTTP 요청의 엔트리 포인트 역할을 합니다.
- 스레드풀: 서블릿 컨테이너는 스레드풀에서 요청을 처리할 스레드를 할당하고, 이를 통해 요청의 병렬 처리를 지원합니다. 여기까지는 서블릿 컨테이너의 관할입니다.
- DispatcherServlet은 Spring의 Servlet WebApplicationContext에 연결되어 있어, 스프링 컨테이너와 상호작용하여 Spring Bean을 관리합니다.
- HandlerMapping을 통해 컨트롤러 매핑:
- Spring 컨테이너 관할: DispatcherServlet은 스프링의 Servlet WebApplicationContext에서 HandlerMapping을 통해 요청에 적합한 컨트롤러를 찾습니다.
- Bean 관리: 이 단계부터 HandlerMapping, 컨트롤러 등은 모두 스프링 컨테이너의 관리하에 있습니다. 스프링 컨테이너는 이 Bean을 관리 및 주입하여 객체 생명 주기를 담당합니다.
- HandlerAdapter의 위임:
- Spring 컨테이너 관할: DispatcherServlet은 매핑된 핸들러를 실행하기 위해 HandlerAdapter를 호출합니다. 이 어댑터는 적절한 컨트롤러 메서드를 호출하여 비즈니스 로직을 수행할 준비를 합니다.
- 서비스 및 리포지토리 계층을 통해 데이터 처리:
- Root WebApplicationContext 관할: 서비스 및 리포지토리 Bean은 일반적으로 Root WebApplicationContext에서 관리됩니다. 이 컨텍스트는 애플리케이션의 비즈니스 로직과 데이터 계층을 포함하여 관리합니다.
- 연관성: Root 컨텍스트는 서블릿 컨텍스트의 상위 계층에 위치하여, 공통적인 비즈니스 로직 및 데이터 처리 로직을 다른 서블릿 컨텍스트와 공유할 수 있습니다.
- 컨트롤러의 반환값 처리 (ViewName과 Model):
- ViewName과 Model 객체는 DispatcherServlet에 의해 ViewResolver에 전달됩니다. 이 작업도 스프링 컨테이너의 Servlet WebApplicationContext에서 관리됩니다.
- ViewResolver에 의한 View 반환:
- Spring 컨테이너 관할: ViewResolver는 스프링 컨테이너에 의해 관리되며, 반환할 View를 결정합니다.
- 예를 들어, JSP는 서블릿 컨테이너에서 렌더링되는 반면, Thymeleaf 같은 다른 템플릿 엔진은 스프링과 협력하여 처리됩니다.
- 응답 생성 및 반환:
- 서블릿 컨테이너 관할: DispatcherServlet이 완성된 View와 Model 데이터를 HttpServletResponse 객체에 담아 클라이언트로 반환합니다.
- 스레드 반환: 서블릿 컨테이너는 처리된 스레드를 스레드풀로 반환하여 재사용할 준비를 합니다.
'질문과 답변 > Java, Spring' 카테고리의 다른 글
Java, JVM (1) | 2024.11.13 |
---|---|
Spring, Spring Boot (4) (1) | 2024.11.06 |
Spring, Spring Boot (2) (0) | 2024.10.31 |
Spring, Spring Boot (1) (1) | 2024.10.25 |