학습목표
- 외부 API 호출 하는 방법
- 어노테이션이 어떤 기능을 하는지 정리
- @RestController @RequestMapping, @GetMapping, @Service, @Component @Configuration
- @SpringBootApplication
- Lombok : @Getter, @Setter, @Data, @Builder
- 스프링 프레임워크의 DI에 대해서, 면접 때 설명할 수 있는 수준으로 정리
외부 API 호출하는 방법
- RestTemplate 을 사용할 수도 있고, 실무에서는 Feign Client 또는 WebClient를 많이 사용 합니다.
어노테이션이 어떤 기능을 하는지 정리
- @RestController (@Controller + @ResponseBody)
- @Controller
- 일반적으로 HTTP requests를 @Controller로 어노테이션 지정된 클래스에서 핸들링된다.
- 그리고 String이면 리턴값이 뷰 이름으로 인식된다.
- 아래로 예를 들면 /greeting으로 Get 리퀘스트를 하면 GreetingController가 "greeting"이라는 View의 이름으로 반환을 해준다. View는 HTML컨텐츠를 렌더링하는 것을 책임진다. View에서 컨트롤러의 정보를 보여준다.
- 스프링이 자동으로 스프링 Bean으로 등록한다. (내부에 @Component 애노테이션이 있어서 컴포넌트 대상이 됨.)
- @ResponseBody + @RequestBody
- 스프링 MVC는 다음의 경우에 HTTP 메시지 컨버터를 적용한다.
- HTTP 요청 : @RequestBody, HttpEntity(RequestEntity)
- HTTP 응답 : @ResponseBody, HttpEntity(ResponseEntity)
- @Controller
package com.example.servingwebcontent;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class GreetingController {
@GetMapping("/greeting")
public String greeting(@RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
model.addAttribute("name", name);
return "greeting";
}
}
//org.springframework.http.converter.HttpMessageConverter
//HTTP 메시지 컨버터 인터페이스
package org.springframework.http.converter;
public interface HttpMessageConverter<T> {
boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
List<MediaType> getSupportedMediaTypes();
T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException;
void write(T t, @Nullable MediaType contentType, HttpOutputMessage
outputMessage)
throws IOException, HttpMessageNotWritableException;
}
- 스프링 부트는 다양한 메시지 컨버터를 제공하는데, 대상 클래스 타입과 미디어 타입 둘을 체크해서 사용여부를 결정한다. 만약 만족하지 않으면 다음 메시지 컨버터로 우선순위가 넘어간다.
0 = ByteArrayHttpMessageConverter
1 = StringHttpMessageConverter
2 = MappingJackson2HttpMessageConverter
- ByteArrayHttpMessageConverter : byte[] 데이터를 처리한다.
- 0. 클래스 타입: byte[] , 미디어타입: */* ,
요청 예) @RequestBody byte[] data
응답 예) @ResponseBody return byte[] 쓰기 미디어타입 application/octet-stream - 1. StringHttpMessageConverter : String 문자로 데이터를 처리한다. 클래스 타입: String , 미디어타입: */*
요청 예) @RequestBody String data
응답 예) @ResponseBody return "ok" 쓰기 미디어타입 text/plain - 2. MappingJackson2HttpMessageConverter : application/json
- 클래스 타입: 객체 또는 HashMap , 미디어타입 application/json 관련
- 요청 예) @RequestBody HelloData data
- 응답 예) @ResponseBody return helloData 쓰기 미디어타입 application/json 관련
- @RequestMapping
- HTTP 매서드를 기준을 가지고 매핑해주는 애노테이션이다.
- Path, method, Headers
- Produces, Consumes
- 등 적용할 수 있다.
- 가장 우선순위가 높은 핸들러 매핑과 핸들러 어댑터는 RequestMappingHandlerMapping ,RequestMappingHandlerAdapter 이다.
- @RequestMapping 의 앞글자를 따서 만든 이름인데, 이것이 바로 지금 스프링에서 주로 사용하는 애노테이션 기반의 컨트롤러를 지원하는 매핑과 어댑터이다. 실무에서는 99.9% 이 방식의 컨트롤러를 사용한다.
- 요청 정보를 매핑한다. 해당 URL이 호출되면 이 매서드가 호출된다. 애노테이션을 기반으로 동작하기 때문에, 매서드의 이름은 임의로 지으면 안된다.
- HTTP 매서드를 기준을 가지고 매핑해주는 애노테이션이다.
- @GetMapping
- @RequestMapping을 method가 Get인 경우 적용하는 HTTP 매서드 매핑 애노테이션이다.
//@GetMapping(value="/new-form")
@RequestMapping(value = "/new-form", method = RequestMethod.GET)
- @Service
- 컴포넌트 스캔 대상이 됨. (@Component가 내부에 존재)
- 스프링 비지니스 로직에 적용하는 애노테이션이다.
- @Component
- 컴포넌트 스캔을 먼저 알아야 한다.
- '컴포넌트 스캔' : 스프링에서 설정 정보가 없어도 자동으로 스프링 빈에 등록하는 기능
- @Component를 가진 모든 대상을 가져와서 빈에 등록하기 위해 찾는 과정이다.
- 빈 이름 기본 전략 : 가장 앞 문자를 소문자로 바꾼 것이 빈 이름이 된다.
- applicationContext를 조회하여 빈의 id를 확인해보면 클래스 앞글자 소문자로 저장이 되는 것을 확인할 수 있다.
- 빈 이름을 수동으로 정하는 방법은 @Component("지정할 이름")
- 컴포넌트 스캔을 먼저 알아야 한다.
- @Configuration
- Bean들이 정의된 클래스의 애노테이션이다.
- applicationContext에 저장된다.
- @SpringApplication 은 스프링 애플리케이션을 main()로 부터 쉽게 로딩하는 기능이다.
- @SpringBootApplication
- 스프링 유저들 대부분은 auto-configuration 기능을 좋아한다.
- @EnableAutoConfiguration
- 스프링 부트의 의존성인 org.springframework.boot:spring-boot-autoconfigure 를 살펴보면
- 하위 여러 클래스들이 존재하는데 이런 키 값들이 명시된 많은 클래스 들이 autoconfiguration의 대상이 된다.
-
- @ComponentScan @Component
- @Configuration
- 3가지 기능을 활성화 할 수 있습니다.
- Lombok
- @Getter, @Setter
- 위 애노테이션을 적용하면 getter,setter를 따로 생성하지 않아도 사용할 수 있다.
- @Data
- @Data는 @ToString, @EqualsAndHashCode, @Getter, @Setter, @RequiredArgsConstructor을 한번에 사용하는 강력한 어노테이션이다. 강력한 어노테이션인 만큼 그에 따른 부작용도 많다.
- @Builder
- 기본적으로 매서드, 생성자에먼 붙일 수 있고, 파라미터를 활용하여 빌더 패턴을 자동으로 생성해준다.
- Builder 사용시 매개변수를 최소화하자.
- 생성자를 필요 조건에 따라 지정하고 그 위에 @Builder를 붙이는게 바람직하다.
- 필요한 매개변수만 받아 생성시에 오류를 방지할 수 있다.
- @Getter, @Setter
스프링 프레임워크의 DI
- DI의 뜻은 기본적으로 Object가 필요로 할때 자체적으로 구성하도록 하는 대신에 Object의 종속성을 제공하는 것입니다. 장점으로는 stub out, mocking을 할 수 있으므로 테스트에 유용한 기술이다.
- 종속성은 다양한 방법 (예: 생성자 주입나 setter 주입)이 있습니다. 스프링 같은 프레임워크를 통해서도 가능하지만 필수적인 것은 아닙니다. 인스턴스화 및 object를 옮기는 것을 프레임워크를 적용하는 것도 좋은 방법이다.
- @Componet나 @Configuration 을 통해 스프링 빈에 등록된 것들은 @Autowired를 통해 의존성 주입이 가능합니다.
- 의존성 주입하는 케이스는 다음과 같은 경우의 수가 있다.
- 해당 타입의 빈이 없는 경우
- setter로 의존성 주입을 받는 경우라면, 필드 에 주입시에 required=false로 설정하여 주입없이 빈에 등록할 수 있다.
- 해당 타입의 빈이 한 개인 경우
- 해당 타입의 빈이 여러 개인 경우
- 빈 이름으로 시도
- 같은 이름으로 찾으면 해당 빈 사용
- 같은 이름 못찾으면 실패
- 빈 이름으로 시도
같은 타입의 빈이 여러개 일 때 처리방법
- @Primary
- 해당 타입의 빈 모두 주입 받기
- @Qualifies (빈 이름 주입하기)
→ Primary가 좀 더 타입세이프 하므로 recommended
- 해당 객체의 유일한 생성자에 인자가 빈에 등록 되있으면 autowired를 입력하지 않아도 자동으로 의존성 주입이 된다. 스프링 4.3이후
- 만약 이전에 빈으로 등록되지 않은 객체라면 autowired를 할지라도 불러오지 못한다
- 레퍼런스에서 권장하는 방법은 생성자를 통해서 주입하라고 한다
- 이유는 생성자는 필수 사항이므로 주어진 인자가 반드시 빈에 등록되길 강제할 수 있다
- 그러나 순환참조 문제가 있을시에는 필드나 세터를 이용
출처
- 스프링부트 공식문서
https://docs.spring.io/spring-boot/docs/current/reference/html/
- 김영한 스프링 MVC 강의