Backend/SpringBoot

SpringBoot 1주차 스터디 - 어노테이션, 의존성 주입(Dependency Injection)

가은파파 2022. 3. 29. 00:06

학습목표

  • 외부 API 호출 하는 방법
  • 어노테이션이 어떤 기능을 하는지 정리
    • @RestController @RequestMapping, @GetMapping, @Service, @Component @Configuration
    • @SpringBootApplication
    • Lombok : @Getter, @Setter, @Data, @Builder
  • 스프링 프레임워크의 DI에 대해서, 면접 때 설명할 수 있는 수준으로 정리

 

외부 API 호출하는 방법

  • RestTemplate 을 사용할 수도 있고, 실무에서는 Feign Client 또는 WebClient를 많이 사용 합니다. 

RestTemplate 의존성 주입

 

어노테이션이 어떤 기능을 하는지 정리

  • @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)

 

 

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이 호출되면 이 매서드가 호출된다. 애노테이션을 기반으로 동작하기 때문에, 매서드의 이름은 임의로 지으면 안된다.
  • @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의 대상이 된다.

AutoConfiguration 설정 파일

    • @ComponentScan @Component
    • @Configuration
    • 3가지 기능을 활성화 할 수 있습니다.
  • Lombok
    • @Getter, @Setter
      • 위 애노테이션을 적용하면 getter,setter를 따로 생성하지 않아도 사용할 수 있다.
    • @Data
      • @Data는 @ToString, @EqualsAndHashCode, @Getter, @Setter, @RequiredArgsConstructor을 한번에 사용하는 강력한 어노테이션이다. 강력한 어노테이션인 만큼 그에 따른 부작용도 많다.
    • @Builder
      • 기본적으로 매서드, 생성자에먼 붙일 수 있고, 파라미터를 활용하여 빌더 패턴을 자동으로 생성해준다.
      • Builder 사용시 매개변수를 최소화하자.
        • 생성자를 필요 조건에 따라 지정하고 그 위에 @Builder를 붙이는게 바람직하다.
        • 필요한 매개변수만 받아 생성시에 오류를 방지할 수 있다.

스프링 프레임워크의 DI

  • DI의 뜻은 기본적으로 Object가 필요로 할때 자체적으로 구성하도록 하는 대신에 Object의 종속성을 제공하는 것입니다. 장점으로는 stub out, mocking을 할 수 있으므로 테스트에 유용한 기술이다. 
  • 종속성은 다양한 방법 (예: 생성자 주입나 setter 주입)이 있습니다. 스프링 같은 프레임워크를 통해서도 가능하지만 필수적인 것은 아닙니다. 인스턴스화 및 object를 옮기는 것을 프레임워크를 적용하는 것도 좋은 방법이다.

 

  • @Componet나 @Configuration 을 통해 스프링 빈에 등록된 것들은 @Autowired를 통해 의존성 주입이 가능합니다.
  • 의존성 주입하는 케이스는 다음과 같은 경우의 수가 있다.
  1. 해당 타입의 빈이 없는 경우
    • setter로 의존성 주입을 받는 경우라면, 필드 에 주입시에 required=false로 설정하여 주입없이 빈에 등록할 수 있다.
  2. 해당 타입의 빈이 한 개인 경우
  3. 해당 타입의 빈이 여러 개인 경우
    • 빈 이름으로 시도
      • 같은 이름으로 찾으면 해당 빈 사용
      • 같은 이름 못찾으면 실패

같은 타입의 빈이 여러개 일 때 처리방법

  • @Primary 
  • 해당 타입의 빈 모두 주입 받기
  • @Qualifies (빈 이름 주입하기) 

→ Primary가 좀 더 타입세이프 하므로 recommended

 

  • 해당 객체의 유일한 생성자에 인자가 빈에 등록 되있으면 autowired를 입력하지 않아도 자동으로 의존성 주입이 된다. 스프링 4.3이후
  • 만약 이전에 빈으로 등록되지 않은 객체라면 autowired를 할지라도 불러오지 못한다
  • 레퍼런스에서 권장하는 방법은 생성자를 통해서 주입하라고 한다
    • 이유는 생성자는 필수 사항이므로 주어진 인자가 반드시 빈에 등록되길 강제할 수 있다
    • 그러나 순환참조 문제가 있을시에는 필드나 세터를 이용

 

출처

- 스프링부트 공식문서

https://docs.spring.io/spring-boot/docs/current/reference/html/

 

Spring Boot Reference Documentation

The reference documentation consists of the following sections: Legal Legal information. Getting Help Resources for getting help. Documentation Overview About the Documentation, First Steps, and more. Getting Started Introducing Spring Boot, System Require

docs.spring.io

- 김영한 스프링 MVC 강의

https://inf.run/N9jk

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -

www.inflearn.com