[Spring] 스프링 입문 공부3 !

석연걸·2025년 1월 24일

스파르타 코딩클럽

목록 보기
11/17

Spring Annotation

@Slf4j

  • 인터페이스이며, 그 구현체로 Logback 같은 라이브러리를 선택
  • 실제 개발에서는 Spring boot가 기본적으로 제공하는 Logback을 사용

  • Logging
    • 쓰레드 정보, 클래스 이름과 같은 부가적인 정보를 함께 확인 가능
    • 실제론 별도의 로깅 라이브러리를 통해 Console에 로그를 출력한다.
    • Log Level 설정을 통해 원하는 메시지를 출력하며, 로그 메시지를 일자별로 모아 외부 저장소에 저장하기도 한다.
      • Log Level
        • TRACE > DEBUG > INFO > WARN > ERROR
        • 예시 코드
        package com.example.springbasicannotation.controller;
         import lombok.extern.slf4j.Slf4j;
         import org.springframework.web.bind.annotation.*;
         @Slf4j
         @RestController
         public class Slf4jController {
        // log를 사용할 때에는 {}, value 로 사용할 것.
        // 왜냐하면 +로 사용할 때에는 문자 연산을 무조건 해버리기 때문이다.
             @RequestMapping("/logging")
             public String logging() {
                String sparta = "Sparta";
                // TRACE -> DEBUG -> INFO -> WARN -> ERROR
                log.trace("문자 trace={}", sparta);
                log.debug("문자 debug={}", sparta);
                // default
                log.info("문자 info={}", sparta);// 문자 연산을 진행하지 않는다.
                log.warn("문자 warn={}", sparta);
                log.error("문자 error={}", sparta);
                log.info("문자 info " + sparta); // 문자 연산을 먼저 해버린다.
                return "success";
            }
        }
        • 여기서 info, warn, error만 나오는데 그 이유는 default가 info로 설정돼있기 때문이며, default를 trace로 바꾸면 전부 다 출력

@Controller 와 @RestController

  • Annotation 기반의 Spring에서 Handler를 만들 때 사용

@Controller

  • ★ View가 있는 경우에만 사용
  • 즉 Template Engine인 Thymeleaf나 JSP를 사용하는 경우

  • Thymeleaf 예시
    • 의존성 추가 : implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    • main/resources/templates가 기본 경로로 설정된다.
    • 즉 build.gradle에 의존성을 추가하면 Spring boot가 알아서 설정해줌

@RestController

  • ★ 응답할 데이터가 있는 경우에만 사용된다.
  • 현재는 대부분 @RestController를 사용하여 API가 만들어짐 (Restful API)
  • 반환 값으로 View를 찾는게 아니라 HTTP Message Body에 Data를 입력
  • 동작 순서

@Component

  • Spring Bean에 등록하는 역할을 수행한다.
    • Spring Bean은 애플리케이션의 구성요소를 정의하는 객체이다.
    • Servlet을 Servlet 컨테이너에 등록하는 것과 같은 역할을 함

  • @Indexed : Spring Bean에 더 빠르게 등록되도록 도와주는 어노테이션

@Target

  • @Target이 선언된 하위 어노테이션이 어떤 범위에 적용될지 설정
  • ElementType Enum 속성
    • ex) @Target(ElementType.ANNOTATION_TYPE)
    • 각각의 Enum마다 적용되는 범위가 주석에 설명돼있음

@Retention

  • 하위 어노테이션이 얼마나 오래 유지되는지를 결정
  • RetentionPolicty Enum 속성
    • ex) @Retention(RetentionPolicity.RUNTIME)
    • SOURCE
      • 소스 코드 (.java)에서만 유지된다.
      • 컴파일 과정에서 어노테이션 정보가 사라짐
    • CLASS
      • 컴파일된 클래스 파일(.class)에 저장되지만, JVM이 실행시 읽지 않는다. (주석과 같음)
      • Default 값이다.
    • RUNTIME
      • 클래스 파일에 저장되고, JVM에 의해 런타임 시점에 읽을 수 있다.
      • 즉, 실제 런타임 시점의 코드에 반영되어 영향을 준다.

@Documented

  • Javadoc 등의 문서화 도구에 의해 문서화돼야 함을 나타낸다.

다시 보는 @Controller

  • @Target
    • Class, Interface, Enum, Annotation, Record Declaration에 적용할 수 있다.
  • @Retention
    • 클래스 파일에 저장되고, JVM에 의해 런타임 시점에 읽을 수 있다.
  • @Documented
    • Javadoc등의 문서화 도구에 의해 문서화가 돼야 함
  • @Component
    • Spring Bean에 등록하며, 싱글톤으로 관리된다.

다시 보는 @RestController

  • @Controller에 @ResponseBody가 결합된 어노테이션
  • @Controller와 다르게 메서드마다 @ResponseBody를 추가하지 않아도 됨

  • @ResponseBody
    • @ResponseBody는 Target({ElementType.TYPE, ElementType.METHOD}) 이지만, @RestController는 Target(ElementType.TYPE)으로 제한하였다.

    • 즉 @RestController는 ElementType.TYPE 만 사용 가능하다.

@RequestMapping

  • 특정 URL로 요청을 보내면, 들어온 요청을 Controller 내부의 특정 메서드와 Mapping 하기 위해 사용된다.
  • 단순히 URL로 Mapping 하는 것이 아닌 여러가지 요소(URL, 메서드등)를 조합하여 Mapping 한다

  • URL path /example만 Mapping한다. (/example/ 이런 식은 안됨)
  • 속성값들을 설정할 때 배열 형태로 다중 설정이 가능하다.
    • ex) RequestMapping({/example1, /example2, ...})

  • HTTP Method 모두 허용한다. (GET, POST, PUT, PATCH, DELETE 등)
  • 메서드 속성으로 HTTP Method를 지정하면 지정된 것만 허용한다.
    • ex) POST를 지정하면 POST만 허용함 (나머지 허용 X)

  • Restful API의 계층 구조
    • ex) users/{userId}, category/{categoryId}/product/{productId}
  • prefix로 선언할 URL을 클래스 레벨에 적용할 때 주로 사용

@GetMapping

  • @Target(ElementType.METHOD) 메서드 레벨에 해당 어노테이션을 적용한다.
  • 내부적으로 @RequestMapping(..., method = RequestMethod.GET)을 사용하고 있다.
  • @PostMapping, @DeleteMapping, @PutMapping, @PatchMapping 등 모두 다 가능하다.

❓ 그러면 이렇게 편리한 Mapping 들이 있으니 RequestMapping은 사용하지 않아도 되는거 아니야 ⁉

  • 위 Mapping 들의 Target은 메소드 레벨만이다.
  • 반면 RequestMapping의 Target은 클래스와 메소드 레벨에 적용이 가능하다.
  • 즉, 클래스 레벨을 사용해야 될 때 RequestMapping을 사용한다 !!

@PathVariable

  • 비연결성(Connectionless)을 극복하여 데이터를 전달하기 위한 방법
  • URL로 전달된 값을 파라미터로 받아오는 역할을 수행

  • 중괄호에 둘러싸인 값이 경로변수를 뜻한다.
    • ex) users/{id}

  • @PathVariable로 설정된 경로변수는 반드시 값을 가지고 있어야 하며, 값이 없으면 응답 코드인 404 Not Found Error 발생

  • 최근엔 Restful API를 설계하는 것이 기준이 되며, 해당 어노테이션의 사용 빈도가 많아짐

  • @PostVariable 규칙
    • 파라미터 변수명과 PathVariable 변수명이 같다면 생략이 가능
      • 생략 X
        • GetMapping("/{postId}") // value 생략
          public String pathVariableV1(@PathVariable("postId") Long data) {}
      • 생략 O
        • GetMapping("/{postId}") // value 생략
          public String pathVariableV1(@PathVariable Long postId) {}

    • @PathVariable 다중 사용 가능
      • GetMapping("/{postId}/comments/{commentsId})
        public String PathVariableV3(@PathVariable Long postId, @PathVariable Long commentsId) {}

특정 파라미터 매핑

  1. Parameter 추가 매핑
  • ex) @GetMapping(value = "/users", params = "gender=man")
  • 실제 URL GET localhost:8080/users?gender=man 파라미터가 있어야 호출된다.
    • 파라미터가 없으면 응답 코드 400 Bad Request Error 발생

  1. 특정 Header 매핑
  • ex) @PostMapping(value = "/users", headers = "Content-Type=application/json")

  1. MediaType 매핑, consumes(수용)
  • ex) @PostMapping(value = "/users", consumes = "Content-Type=application/json)
  • HTTP Header Content-Type(요청)과 매핑된다
  • consumes 속성 값으로는 이미 Spring에서 제공하는 Enum인 MediaType.APPLICATION_JSON_VALUE 형태로 사용한다.

  1. MediaType 매핑 produces(제공)
  • 요청 헤더의 Accepts 하는 값에 따라 produces 하는 값이 변한다.
  • HTTP 요청 Accept Header에 MediaType이 있어야 한다.
  • consumes 속성 사용법과 같다.

  1. 다양한 Enum 형태

0개의 댓글