Spring Boot는 spring 환경기반으로 빠르게 production 수준의 독립적인 애플리케이션을 만들 수 있도록 도와준다.
spring framework에 필요한 설정들 및 제3라이브러리 기본 설정을 제공해준다.
대표적으로 톰캣이 있다.
Spring Boot를 쓰는 이유는 크게 편리한 의존성 관리, 자동설정, 내장 웹서버(톰캣) 설정이다.
의존성 관리 (maven 기준 설명)
Dependency에 spring-starter-web이 들어있는데 이것만 있어도 어마어마한 의존성들이 들어온다.
그 이유는 spring-boot-starter의 역할이다. spring-boot-starter는 의존성을 관리한다.
의존성 관리를 받는 원리는, spring-boot-starter-parent가 있다. 올라가다보면 spring-boot-dependencies가 있다. 여기서 스프링부트가 사용하는 주요 모든 라이브러리들의 버전들을 관리한다. dependency management로도 dependency 관리를 할 수 있지만 차이점이 있다.
parent로 관리를 받는것과 dependency management로 관리를 받는 것의 차이는 parent로 관리하면 의존성관리 및 인코딩, 자바버전 등등 설정을 해주고 management는 그렇지 않기 때문에 parent를 추천한다.
자동 설정
앞서 스프링 부트는 톰캣이 내장되어있다고 했다.
어떻게 톰캣이 내장될 수 있을까?
정답은 @EnableAutoConfiguration이다.
사실상 스프링 부트에서 빈 등록은 두번의 단계를 거쳐 진행된다.
첫번째로는 @ComponentScan에서 빈을 등록하고 그 다음으로 @EnableAutoConfiguration에서 읽어온 빈들을 또 등록한다. 그래서 스프링 부트에서는 @EnableAutoConfiguration가 없어도 빈을 등록할 수있지만 에러가 날 것이다.
이유는 서블릿 웹 서버 팩토리의 빈은 자동으로 @EnableAutoConfiguration가 만들어주기 때문이다. 그래서 웹 애플리케이션 타입으로 하려면 필수다.
@EnableAutoConfiguration를 쓰지않으려면 static 메서드를 쓰지않고 main application class를 instance화 해서 커스터마이징하면 된다.
@ComponentScan
@Configuration
// @SpringBootApplication
public class YappianApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(YappianApplication.class)
application.setWebApplicationType(WebApplicationType.NONE);
application.run(args);
}
}
// 이것은 웹애플리케이션은 아님.
@EnableAutoConfiguration 동작과정
springboot-autoconfigure안에 META-INF안에 spring.factories가 있다.
spring.factories를 보면 키값으로 autoconfigure.EnableAutoConfiguration=\가 있고 밸류값으로 여러개의 Configuration 클래스들이 있다.
@ComponentScan에서 등록한 빈이 @EnableAutoConfiguration에 오버라이딩 될 때가 있다. 이때 @ConditionalOnMissingBean으로 해결을 하면된다.
@ConditionalOnMissingBean은 이 빈이 있으면 등록을 안하고 없으면 빈 등록을 한다.
내장 서블릿 컨테이너
서블릿과 서블릿 컨테이너의 이해
우선 서블릿 컨테이너는 웹 애플리케이션 서버중에서 HTTP 요청을 받아 처리하는 역할을 한다. 서블릿을 동작하도록 한다.
서블릿 컨테이너에는 아파치 톰캣, 제티, 네티, 언더토우 등이 있다.
서블릿은 javax.servlet.Servlet 인터페이스를 구현한것이고 서블릿 컨테이너 내에 등록된 후 서블릿 컨테이너에 의해 생성, 호출, 소멸이 이뤄진다.
일반적으로 서블릿은 HttpServlet을 상속받은 서블릿을 의미한다. HttpServlet은 GenericServlet을 상속받으며 GenericServlet의 service 메서드를 HTTP 프로토콜 요청 메서드에 적합하게 재구현한것이다.
과정
- 웹 브라우저에 의해 요청이 HTTP 프로토콜로 변환이 되어서 서블릿 컨테이너에게 전달된다
- 이를 서블릿 컨테이너가 해석하고 재조합하여 웹 프로그래머가 작성한 서블릿으로 전달된다.
- 서블릿의 매개변수로 ServletRequest와 ServletResponse를 가지는 service 메소드가 호출된다
- 그러면 HttpServlet의 service 메서드 내에서 HTTP 요청 메서드에 의해 여러 doXXX 메서드로 분기돼어 처리된다.
- 클라이언트로부터 전달받은 메시지는 Servlet Request 인터페이스를 통해 전달된다.
이러한 설정을 자동설정에서 해준다.
spring.factories에서 ServletWebServeFactoryAutoConfiguration 클래스가 있다. 이것이 서블릿 웹 서버를 설정한다.
여기에는 톰캣, 네티, 언더토우가 있었다.
톰캣에 더 들어가보니 톰캣을 만들고 서블릿 설정, 컨텍스트 설정 등등 여러 설정이 있었다.
즉 자동설정으로 내장 서블릿 컨테이너가 만들어졌다. 그리고 여기서 서버를 커스터마이징도 했는데 이 서버는 DispatcherServlet에서 등록을 한다.
이 둘은 왜 따로 떨어져있을까?
서블릿 컨테이너는 사용자 설정에 따라서 달라질 수 있지만, 서블릿은 변하지 않기 때문에 분리되었다.
따라서 DispatcherServlet은 어떠한 서블릿 컨테이너를 사용하든지간에, 서버를 만든다.
정리하자면 ServletWebServerFactoryAutoConfiguration에서 서블릿 컨테이너를 만들고 설정하고 DispatcherServletAutoConfiguration에서 서블릿을 만들고 서블릿 컨테이너에 등록을 한다.
DispatcherServlet
Http Servlet을 상속하여 만든 Spring MVC의 핵심 클래스이다.
동작과정은 다음과 같다.