Spring/Spring MVC

[Spring] HTTP 요청 맵핑 - 커스텀 애노테이션

TheWing 2020. 11. 15. 18:35

Custom Annotation

  • 직접 커스터마이징 하는것이 커스텀 애노테이션이다.

@RequestMapping 애노테이션을 메타 애노테이션으로 사용하기

  • @GetMapping 같은 커스텀한 애노테이션을 만들 수 있다.

메타(Meta) 애노테이션

  • 애노테이션에 사용할 수 있는 애노테이션
  • 스프링이 제공하는 대부분의 애노테이션은 메타 애노테이션으로 사용할 수 있다.

조합(Composed) 애노테이션

  • 한개 혹은 여러 메타 애노테이션을 조합해서 만든 애노테이션
  • 코드를 간결하게 줄일 수 있다.
  • 보다 구체적인 의미를 부여할 수 있다.

@Retention

  • 해당 애노테이션 정보를 언제까지 유지할 것인지.
  • Source: 소스 코드까지만 유지. 즉, 컴파일 하면 해당 애노테이션 정보는 사라진다는 이야기이다
  • Class: 컴파인 한 .class 파일에도 유지. 즉 런타임 시, 클래스를 메모리로 읽어오면 해당 정보는 사라진다.
  • Runtime: 클래스를 메모리에 읽어왔을 때까지 유지! 코드에서 이 정보를 바탕으로 특정 로직을 실행할 수 있다.

@Target

  • 해당 애노테이션을 어디에 사용할 수 있는지 결정한다.

@Documented

  • 해당 애노테이션을 사용한 코드의 문서에 그 애노테이션에 대한 정보를 표기할지 결정한다.

메타 애노테이션

예제

@RequestMapping 만 사용한 예제

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@RequestMapping(method = RequestMethod.GET, value = "/hello")
public @interface GetHelloMapping {
}
@Controller
public class SampleController {

    @GetHelloMapping
    @ResponseBody
    public String hello() {
        return "hello";
    }
}
@WebMvcTest
public class SampleControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Test
    public void helloTest() throws Exception {
        mockMvc.perform(get("/hello"))
                .andDo(print())
                .andExpect(status().isOk())
        ;
    }
}
  • 이렇게 테스트하면 실패이다.

성공 예제

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.lang.annotation.*;

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME) //RUNTIME 동안 애노테이션 정보를 유지
@RequestMapping(method = RequestMethod.GET, value = "/hello")
public @interface GetHelloMapping {
}
@WebMvcTest
public class SampleControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Test
    public void helloTest() throws Exception {
        mockMvc.perform(get("/hello"))
                .andDo(print())
                .andExpect(status().isOk())
        ;
    }
}
@Controller
public class SampleController {

    @GetHelloMapping
    @ResponseBody
    public String hello() {
        return "hello";
    }
}
  • Retention을 지정해줘야 성공한다

Reference