티스토리 뷰

반응형

Spring MVC Framework는 HandlerMapping/Adpater라는 인터페이스를 통해 URL의 테이블을 만들고

클라이언트가 요청한 URL을 매핑된 스프링 빈(빈의 이름이 URL에 매핑된다)에 연결을 하는 역할을 해준다

 

이때 이전의 방식이라면 빈을 등록할 때 @Component라는 어노테이션을 추가해 일일이 등록을 해야 했지만

스프링 MVC에서는 @Controller라는 어노테이션을 활용하여 매우 쉽게 스프링 빈을 등록할 수 있다

(Handler == Controller)

 

@Controller

아래의 예시와 같이 클래스 단에 @Controller라고 어노테이션을 작성하게 되면

해당 클래스에 속한 메서드들을 스프링 빈으로 지정한다

@Controller
public class ControllerExample {
	
    @RequestMapping("/example1")
    public void controllerExample1() {
    }
    
    @RequestMapping("/example2")
    public void controllerExample2() {
    }
    
    @RequestMapping("/example3")
    public void controllerExample3() {
    }
    
}

그렇다면 @Controller는 어떻게 이 메서드들을 빈으로 매핑해주는가?

사실 굉장히 간단한 원리이다 @Controller 어노테이션을 따라 들어가 보면 @Component 어노테이션이 있는 것을 볼 수 있다

// @Controller를 따라 들어가면 @Component가 있는 것을 볼 수 있다
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

	/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any (or empty String otherwise)
	 */
	@AliasFor(annotation = Component.class)
	String value() default "";

}

또한 Spring MVC에서의 @Controller 같은 경우 주로 View를 반환하기 위해서 사용하는데

아래의 예시와 같이 반환 값을 String으로 주게 되면 자동으로 ViewResolver의 설정된(prefix, suffix) 값을 기준으로 View를 반환한다

@Controller
public class ControllerExample {
	
    @RequestMapping("/example1")
    public String controllerExample1() {
    return "/example1/view";
    }
    
    @RequestMapping("/example2")
    public String controllerExample2() {
    return "/exmaple2/view";
    }
}

 

번외로 @SpringBootApplication을 따라 들어가보면 @ComponentScan이 붙어있는 것을 볼 수 있다

(생략)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
(생략)

 

@RestController

(@Controller도 @ResponseBody를 사용하면 반환값을 데이터로 바꿀 수 있다 하지만 본 글의 목적과 맞지 않아 생략하였다)

 

@Controller가 주로 View를 반환하기 위해 사용했다면 @RestController의 경우

데이터 그 자체를 반환하기 위해 사용한다 View를 반환하던 예시를 똑같이 작성한 후 @RestController로 변경해주면

View를 반환하는 것이 아닌 String 문자열(데이터) 그 자체를 반환된다

@RestController
public class ControllerExample {
	
    @RequestMapping("/example1")
    public String controllerExample1() {
    return "/example1/view"; //문자열 그 자체를 반환
    }
    
    @RequestMapping("/example2")
    public String controllerExample2() {
    return "/exmaple2/view";
    }
}

//결과는 웹 브라우저에 문자열이 그대로 출력 됨

@Controller가 View를 반환하기 위해 ViewResolver를 사용했듯이

@RestController의 경우 HttpMessageConverter를 사용하여 데이터를 반환한다

단순 문자열인 경우에는 StringHttpMessageConverter가 사용되고

객체인 경우에는 MappingJackson2HttpMessageConverter를 사용한다

즉 데이터 종류에 따라서 해당 컨버터가 동작되는 방식이다

 

RestController라는 이름 답게 REST API(REST API란?)를 개발하는데 많이 사용된다

 

@Controller와 @RestController의 차이

둘 다 스프링 빈으로 자동 등록되는 원리는 같으나 차이점의 핵심은 반환 값이 다르다는 것이다

 

@Controller : ViewResolver를 활용하여 View를 반환

@RestController : HttpMessageConverter를 활용하여 데이터를 반환

 

핵심정리

스프링 MVC 프레임워크 동작구조 상

스프링 빈이 등록되어 있어야 클라이언트가 요청하는 URL과 매핑하여 해당 요청이 작동하는데

이 등록과정을 단순화 한게 @Controller, @RestController이다

 

둘이 차이점은 View를 반환하거나 데이터 그 자체를 반환하는 차이를 가진다

 

 

더보기

개인 학습을 위해 작성되는 글입니다.

제가 잘못 알고 있는 점에 대한 지적 / 더 나은 방향에 대한 댓글을 환영합니다.

 

참조 링크:

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard

https://springsource.tistory.com/12

https://mangkyu.tistory.com/49

 

 

반응형
댓글