외장 서버
서버에 톰캣같은 WAS를 설치한 후, WAS에서 동작하도록 서블릿 스펙에 맞춰 코드를 작성한 후 war 파일을 WAS를 전달해 배포하였다.
내장 서버
애플리케이션 코드 내에 WAS가 라이브러리로 내장되어 있다. 개발자는 코드 작성 후 jar로 빌드한 후 해당 jar를 원하는 위치에서 실행하면 WAS도 함께 실행된다.
jar
여러 클래스와 소스를 묶어서 jar(java archive)라는 압축 파일을 만들 수 있다. jvm위에서 직접 실행되거나 다른 곳에서 라이브러리로 사용할 수 있다.
war
jar는 jvm위에서 실행된다면, war는 웹 애플리케이션 서버 위에서 실행된다. 또한 아래와 같은 구조를 지켜야 한다.
서블릿은 ServletContainerInitializer
로 서블릿 컨테이너를 초기화 한다.
@HandlesTypes(AppInit.class)
public class MyContainerInitV2 implements ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
System.out.println("MyContainerInitV2.onStartup");
System.out.println("c = " + c + ", ctx = " + ctx);
for (Class<?> appInitClass : c) {
try {
//new AppInitV1Servlet()과 같은 코드
AppInit appInit = (AppInit) appInitClass.getDeclaredConstructor().newInstance();
appInit.onStartup(ctx);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
애플리케이션 초기화 과정
ServletContainerInitializer
는 파라미터로 넘어오는 Set<Class<?>> c
에 인터페이스 구현체들을 모두 찾아 클래스로 전달한다. @HandlesTypes(AppInit.class)
이므로 AppInit 구현체들을 넘김 appInitClass.getDeclaredConstructor().newInstance();
로 객체를 생성한다.appInit.onStartup(ctx);
서블릿 컨테이너 정보가 담긴 ctx를 전달하며 초기화 코드를 실행한다.실행 과정
ServletContainerInitializer
구현해서 초기화 코드 만듦public class AppInitV2Spring implements AppInit{
@Override
public void onStartup(ServletContext servletContext) {
System.out.println("AppInitV2Spring.onStartup");
//스프링 컨테이너 생성
AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
appContext.register(HelloConfig.class);
//스프링 MVC 디스패처 서블릿 생성, 스프링 컨테이너 연결
DispatcherServlet dispatcherServlet = new DispatcherServlet(appContext);
//디스패처 서블릿을 서블릿 컨테이너에 등록
ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcherV2", dispatcherServlet);
// /spring/* 요청이 디스패처 서블릿을 통하도록
servlet.addMapping("/spring/*");
}
}
AppInit
대신 WebApplicationInitializer
을 구현하면 애플리케이션 초기화를 알아서 해준다.서블릿 컨테이너 초기화를 통해 필요한 서블릿 등록하고, 스프링 컨테이너도 생성해서 등록하였다. 또한 스프링 mvc가 동작하도록 디스패처 서블릿도 중간에 연결했다.
이 방식은 서블릿 컨테이너 위에서 동작하는 것으로, 항상 톰캣 같은 서블릿 컨테이너에 배포를 해야만 동작하는 방식이다. 스프링 부트는 내장 톰캣을 사용하여 이런 부분이 바뀌게 된다.