You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
publicclassAppInitV1ServletimplementsAppInit {
@OverridepublicvoidonStartup(ServletContextcontext) {
System.out.println( "AppInitV1Servlet.onStartup()");
// 순수 서블릿 코드 등록ServletRegistration.DynamichelloServlet = context.addServlet("helloServlet", newHelloServlet());
helloServlet.addMapping("/hello-servlet");
}
}
ServletContext에 서블릿을 등록하고, 등록된 서블릿에 대한 매핑을 해줌
프로그래밍 방식으로 HelloServlet 서블릿을 서블릿 컨테이너에 직접 등록함
HTTP로 /hello-servlet을 호출하면 HelloServlet 서블릿이 실행됨
💡
@WebServlet어노테이션을 통해 서블릿을 등록할 수 있지만, 하드코딩되어 유연한 등록이 불가함. 따라서 위의 방식과 같이 인터페이스를 통해 구현체를 주입받을 수 있도록 하면 외부 설정에 따라 설정을 달리 할 수 있음. 또한, 서블릿 자체도 조건에 따라 분기할 수 있으며 생성자에 필요한 정보를 넘길 수 있음.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
서블릿 컨테이너 초기화
WAS를 실행하는 시점에 필요한 초기화 작업
WAS가 제공하는 초기화 기능을 사옹하면 WAS 실행 시점에 이러한 초기화 과정 진행 가능
과거엔 web.xml을 사용해서 초기화했지만, 지금은 서블릿 스펙에서 자바 코드를 사용한 초기화도 가능
서블릿 컨테이너 초기화 V1
서블릿의 ServletContainerInitalizer 인터페이스를 통해 초기화
서블릿 컨테이너는 실행 시점에 초기화 메소드인 onStartUp()를 호출함. 여기서 어플리케이션에 필요한 기능을 초기화 하거나 등록함
ServletContainerInitalizer
public interface ServletContainerInitializer { public void onStartUp(Set<Class<?>> c, ServletContext ctx) throws ServletException; }Set<Class<?>> c : @HandlesTypes 어노테이션과 함께 사용되어 유연한 초기화 기능 제공.
ServletContext ctx: 서블릿 컨테이너 자체의 기능을 제공함. 이 객체를 통해 필터, 서블릿을 등록
추가로 WAS에게 실행할 초기화 클래스를 설정함
resources/META-INF/services/jakarta.servlet.ServletContainerInitializer파일에 Initializer 구현체의 패키지 경로를 포함하여 지정함이러면 WAS를 실행할 때 해당 클래스를 초기화 클래스로 인식하고 로딩 시점에 실행함
서블릿 컨테이너 초기화 V2
서블릿을 등록하는 2가지 방법
위의 서블릿을 등록하고 실행하면 로그와 HTTP응답을 통해 등록됨을 확인할 수 있음
서블릿 컨테이너를 초기화하는 인터페이스를 정의함
ServletContext에 서블릿을 등록하고, 등록된 서블릿에 대한 매핑을 해줌
프로그래밍 방식으로 HelloServlet 서블릿을 서블릿 컨테이너에 직접 등록함
HTTP로 /hello-servlet을 호출하면 HelloServlet 서블릿이 실행됨
💡@WebServlet어노테이션을 통해 서블릿을 등록할 수 있지만, 하드코딩되어 유연한 등록이 불가함. 따라서 위의 방식과 같이 인터페이스를 통해 구현체를 주입받을 수 있도록 하면 외부 설정에 따라 설정을 달리 할 수 있음. 또한, 서블릿 자체도 조건에 따라 분기할 수 있으며 생성자에 필요한 정보를 넘길 수 있음.
- @HandleTypes 어노테이션에 어플리케이션 초기화 인터페이스를 지정함
- 서블릿 컨테이너 초기화(ServletContainerInitializer)는 파라미터로 넘어오는 Set<Class<?>> c 에 어플리케이션 초기화 인터페이스의 구현체들을 모두 찾아서 클래스 정보로 전달함
- appInit.class.getDeclaredConstructor().newInstance()
- appInit.onStartup(ctx)
💡리플렉션을 활용해 객체를 생성함
어플리케이션 초기화 코드를 직접 실행하면서 서블릿 컨테이너 정보가 담긴 ctx도 함께 전달함
이러한 어플리케이션 초기화 개념을 사용하는 이유
서블릿 컨테이너를 초기화하기위해 ServletContainerInittializer 인터페이스를 구현해야함. 그리고, META-INF/services/jakarta.servlet.ServletContainerInitializer에 해당 구현체에 대한 패스를 지정해줘야함
어플리케이션 초기화는 특정 인터페이스만 구현하면 됨
어플리케이션 초기화는 서블릿 컨테이너에 상관없이 원하는 모양으로 인터페이스를 만들 수 있음. 이를 통해 어플리케이션 초기화 코드가 서블릿 컨테이너에 대한 의존을 줄일 수 있음. ServletContext가 필요없는 어플리케이션 초기화 코드라면 의존을 완전히 제거 가능함
스프링 컨테이너 등록
다음의 과정을 통해 WAS와 스프링을 통합을 진행함
스프링 컨테이너 생성
AnnotationConfigWebApplicationContext가 스프링 컨테이너임.ApplicationContext인터페이스를 구현한 구현체가 AnnotationConifgWebApplicationContext.
애노테이션 기반 설정과 웹 기능을 지원하는 스프링 컨테이너.
appContext.register(HelloConfig.class)컨테이너에 스프링 설정을 추가함(컨트롤러 빈 등록)
스프링 MVC 디스패쳐 서블릿 생성, 스프링 컨테이너 연결
new DispatcherServlet(appContext)코드에서 스프링 MVC가 제공하는 디스패쳐 서블릿을 생성하고, 생성자에 생성했던 스프링 컨테이너를 전달함. → 스프링 컨테이너와 디스패쳐 서블릿 연결
디스패쳐 서블릿에 요청이 들어오면 해당 스프링 컨테이너에 들어있는 컨트롤러 빈을 호출함
디스패쳐 서블릿을 서블릿 컨테이너에 등록
servletContext.addServlet(”dispatcherV2”, dispatcher)디스패처 서블릿을 서블릿 컨테이너에 등록함
/spring/* 요청이 디스패쳐 서블릿을 통하도록 설정
해당 경로를 설정하면 해당 경로와 그 하위 모든 요청은 해당 서블릿을 통하게 됨
실행 과정
스프링 MVC 서블릿 컨테이너 초기화 지원
스프링 MVC는 이러한 서블릿 컨테이너 초기화 작업을 지원함.
서블릿 컨테이너 초기화 과정은 생략하고, 어플리케이션 초기화 코드만 작성하면 됨
WebApplicationInitializer 인터페이스를 구현한 부분을 제외하고는 이전의 AppInitV2Spring과 동일함
WebApplicationInitializer는 스프링이 제공하는 어플리케이션 초기화 인터페이스.
위와같이 3개의 경로와 / 경로에 대해서 총 4개의 서블릿이 매핑되어있음
스프링 MVC가 제공하는 서블릿 컨테이너 초기화 분석
org.springframework.web 의
SpringServletContainerInitializer.class를 확인해보면 다음과 같다.@HandlesTypes어노테이션과ServletContainerInitializer인터페이스를 구현하고 있음을 확인할 수 있다.또한 spring-web 라이브러리의 services하위에 초기화 클래스 파일 정의가 되어있다.
org.springframework.web.SpringServletContainerInitializer결국 서블릿 컨테이너가 초기화에 요구하는것들을 스프링이 제공하는 것.
Beta Was this translation helpful? Give feedback.
All reactions