서블릿 이란?
클라이언트 요청을 처리하고, 그 결과를 다시 클라이언트에게 전송하는 Servlet클래스의 구현 규칙을 지킨 자바 프로그램이다.
이전의 웹 프로그램들은 클라이언트의 요청에 대한 응답으로 만들어진 페이지를 넘겨주었으나, 현재는 동적인 페이지를 가공하기 위해서 웹 서버가 다른 곳에 도움을 요청한 후 가공된 페이지를 넘겨주게 된다.
💨 이때 서블릿을 사용하게 되면 웹 페이지를 동적으로 생성하여 클라이언트에게 반환해 줄 수 있다.
◻ 클라이언트의 요청에 대해 동적으로 작동하는 웹 어플리케이션 컴포넌트html을 사용하여 요청에 응답한다.
◻ Java Thread를 이용하여 동작한다.
◻ MVC 패턴에서 Controller로 이용된다.
◻ HTTP 프로토콜 서비스를 지원하는 javax.servlet.http.HttpServlet 클래스를 상속받는다.
◻ UDP보다 처리 속도가 느리다.
◻ HTML 변경 시 Servlet을 재컴파일해야 하는 단점이 있다.
@WebServlet("/main")
public class main extends HttpServlet {
private static final long serialVersionUID = 1L;
public main() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append("Served at: ").append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
◻ urlPattern("/main")을 따라서 URL이 호출되면 서블릿 코드가 실행된다.
◻ HttpServletRequest를 통해 http 요청정보를 사용한다.
ex) request.getparameter("")등등
◻ HttpServletResponse를 통해 http 응답정보를 사용할 수 있다.
[Servlet의 동작과정]
Servlet은 객체를 생성하고 초기화 작업을 거친 후, 요청을 처리한다.
💨 바로 Servlet이 호출되는 것이 아니다.
Servlet의 생명주기
+@ 톰캣의 서블릿 관리
◻ Servlet 객체를 생성하고 초기화하는 작업은 비용이 많은 작업이므로, 다음요청에 대비해서 이미 생성된 Servlet 객체는 메모리에 남겨둔다.
◻ 톰캣이 종료되기 전이나 reload 전에 모든 Servlet을 제거한다.
💨 톰캣은 자원을 좀 더 아껴가며 Servlet을 사용한다.
EX) Servlet 구현 및 구동
@WebServlet("/test")
public class LifeCycleServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void init(ServletConfig config) throws ServletException {
System.out.println("init called");
super.init();
}
public void destroy() {
System.out.println("destroy called");
super.destroy();
}
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("service called");
super.service(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet 호출");
response.getWriter().append("Served at: ").append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doPOST 호출");
doGet(request, response);
}
}
위와 같은 HttpServlet을 상속받는 LifeCycleServlet 클래스를 구현하였다.
톰캣에 프로젝트를 등록하고 , 해당 URL 인 http://localhost:8080/dynamicSource/test 를 요청한다.
◻ 생명주기가 맞다면
init메소드를 호출해서 생성된 servlet객체를 초기화
=>
service 메소드를 호출
=>
특정 HTTP 메서드를 타고 System.out.println() 내용을 호출 할 것이다.
init -> service -> do~ 메소드를 호출하였다.
브라우저를 reload해보았다.
톰캣이 이미 만들어진 Servlet객체를 메모리에 남겨둔다고 했으니,
service메소드 => do ~ 메소드를 호출하는것이 맞다.
그 후 3분정도 지났는데
위와 같이 서블릿클래스를 다시 로드하면서 destroy, Servlet을 소멸시켰다.
+@ Web Server
+이건 따로 정리
https://gmlwjd9405.github.io/2018/10/27/webserver-vs-was.html
서블릿 컨테이너는 구현되어있는 Servlet 클래스의 규칭에 맞게 서블릿 객체를 생성, 초기화 , 호출, 종료하는 생명주기를 관리한다.
클라이언트의 요청을 받고 응답할 수 있도록 웹 서버와 소캣으로 통신한다.
ex)
Tomcat은 Web Application Server(WAS)중 하나로, Servlet Container 기능을 제공한다.
+@ JVM의 역활은?
서블릿을 사용하는 것은 JVM이 각 요청을 분리된 자바 스레드 내부에서 처리하도록 하는 것.
+@ WAS VS Web Server
◻ 스프링 컨테이너는 Bean의 생명주기를 관리하며, 추가적인 기능을 제공하는 역활을 한다.
◻ Bean을 관리하기 위해 IOC(Inversion of Control Container)가 이용된다.
◻ IOC 컨테이너를 상속하면서 부가기능을 추가한 것이 ApplicationContext이다.
◻ Spring MVC 역시 Servlet Container가 관리하는 거대한 서블릿이라 생각된다. 그래서 Servlet없이 MVC만 있으면 된다고 하는 것은 비지니스 로직을 Spring을 통해 처리한다는 것이지, Servlet이 필요없는것은 아니다.
◻ 정리하자면 Servlet 컨테이너가 Spring Bean에 접근하려면 Spring container를 거쳐야한다.
ㅁ ApplicationContext를 스프링 컨테이너라 하며, XML또는 어노테이션 기반의 자바 설정 클래스로 만들수 있다.
◻ 스프링 컨테이너는 파라미터로 넘어온 config 파일정보를 이용해서 스프링 빈(자바객체)를 등록한다.
◻ new 연산자 사용, 인터페이스 호출, 객체의 생명주기를 spring container가 대신한다.
DI container + DI config => ApplicationContext
+@ 싱글톤 컨테이너
◻ 스프링 컨테이너는 객체의 인스턴스를 싱글톤으로 관리하기 때문에 싱글톤 컨테이너라고도 한다.
◻ 싱글톤 빈을 미리 로딩해서 그 빈이 필요한 즉시 바로 사용될 수 있도록 해준다.
💨 즉 app은 빈이 생성될때까지 기다릴 필요가 없다.
+@ Bean
Bean은 Spring IoC 컨테이너에 의해 인스턴스화, 조립 및 관리되는 객체이다.
◻ Dispatcher Servlet 내부에 서블릿 WebApplicationContext와 Root WebApplicationContext가 동작하는데 얘네 둘이 Spring container에서 동작하는 컨텍스트 들이다.
그렇다면 이 둘을 관리하는 Dispatcher Servlet이 Spring MVC에서 가지는 역활은 무엇일까?
- 배포서술자에 DispatcherServlet 등록한다.
- 웹 컨테이너가 뜰때 DispatcherServlet의 전략 빈들이 생성된다.
- 실제 사용자의 Request가 들어온다.
- 웹 컨테이너는 DispatcherServlet 객체를 생성하고 초기화 한다. (첫 호출시에만)
- 웹 컨테이너가 Request, Response 객체를 생성한다.
- 웹 컨테이너의 쓰레드 풀에서 쓰레드 하나를 할당하여 DispatcherServlet 실행.
- request uri에 알맞은 핸들러(메소드)를 가져온다. (실제 핸들러를 매핑하는 전략은 DispatcherServlet에 주입된 HandlerMapping 구현체에 의해)
- 핸들러를 실행시키기 위하여 핸들러 아답터를 가져온다. (핸들러 클래스 타입마다 적용시킬 아답터가 다르므로)
- 인터셉터의 preHandle 실행
- 실제 컨트롤러 핸들러(메소드) 실행
- 인터셉터의 postHandle 실행
- 개발자가 설정한 View 에 알맞도록 렌더링을 실행하여 결과를 write
- 웹 컨테이너가 response를 보내주고 유저 스레드 반환
https://victorydntmd.tistory.com/154
https://yangbongsoo.gitbook.io/study/servlet_container
https://www.programcreek.com/2013/04/what-is-servlet-container/
https://gmlwjd9405.github.io/2018/10/27/webserver-vs-was.html
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-client
https://taes-k.github.io/2020/02/16/servlet-container-spring-container/