티스토리 뷰

 

@SpringBootApplication 어노테이션과 SpringApplication.run(HellobootApplication.class, args); 는 어떻게 동작 되길래 스프링이 작동되는 걸까? 어떻게 만들어진건지 차근차근 따라가 보자

 

 

서블릿 컨테이너 띄우기

package tobyspring.helloboot;

public class HellobootApplication {

	public static void main(String[] args) {
		
	}

}

일단 스프링을 실행시켜줬던 어노테이션과 메인메서드 블록의 내용을 지우고 시작한다.

 

스프링 부트 설치시 내장형 WAS API 들도 같이 설치가 된다. Tomcat, Jetty, Netty, Undertow

https://gofnrk.tistory.com/73

 

Spring Boot 내장 WAS 종류와 특징

스프링 부트 내장 WAS의 종류와 특징입니다. 최대한 쉽게 적어봤어요. Tomcat ~7버전까지 대규모 트래픽에서 불안정하다 vs 아니다 등의 의견이 분분했고, 8버전은 폭망했지만, 8.5버전으로 대응하여

gofnrk.tistory.com

 

가장 많이 사용하고 있는 Tomcat API를 사용하여 서블릿 컨테이너를 구현해 본다.

일단 서블릿 컨테이너를 띄우면 서버에 접근할 수 있다.

 컨테이너가 띄워져 있어야 반환값을 받을 수 있기때문에 리퀘스트 요청에 404코드를 받은 건 컨테이너가 띄워져 있는 것.

 

서블릿 등록, 요청

클라이언트(Browser)에서 서블릿 컨테이너(Web Server)로 request를 받으면 기능을 수행하고 response하는 웹 컴포넌트(Servlet)를 만들어 보자.

보통 request가 오면 해당 작업을 여러개 서블릿중에 어느 서블릿에게 작업을 위임할지 결정해야 하는데 이 과정을 Mapping한다고 한다.

URI에 맞는 servlet을 찾아 각자의 작업 후 응답하는 작업 중 중복이 되는 코드들 (공통처리, 선처리인 권한이나 인증, 보안, 클라이언트로 화면을 후처리)을 한 곳에서 받아서 각 작업에 맞는 servlet에게 위임하는 작업을 frontController에서 받아 적합한 controller로 위임한다.

위임받은 controller는 넘겨받은 인자로 업무를 수행한 결과를 다시 frontCotroller에 전달하고 frontController는 다시 클라이언트로 결과값을 보낸다.

 

package tobyspring.helloboot;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServer;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;

public class HellobootServletApplication {

	public static void main(String[] args) {

		// 부트 설치시 내장형 tomcat API들도 같이 설치되었다. 해당 API를 사용한다.
		ServletWebServerFactory servletWebServerFactory = new TomcatServletWebServerFactory();

		WebServer webServer = servletWebServerFactory.getWebServer( servletContext -> {

			// 익명클래스인 ServletContextInitializer를 사용하여 servlet을 servletContainer에 추가
			// servlet 이름과 HTTP 프로토콜을 사용하는 Servlet인 HttpServlet 인스턴스를 상속받는다는 익명클래스 추가
			// 익명 클래스로 만드는 이유는 해당 객체가 변수에 담겨 다른곳에 사용될 일이 없으니..
			// frontController는 리퀘스트 요청을 받는 단일인입점으로 들어온 요청에 따른 작업을 다른 servlet 에게 위임하는 역할을 한다.
			servletContext.addServlet("frontController", new HttpServlet() {

				// frontController에서 작업을 위임할 servlet
				final HelloServletController helloController = new HelloServletController();

				// Servlet Lice Cycle
				// 클라이언트 리퀘스트 최초 요청시 1번만 실행되는 초기화 작업용 init 메서드
				@Override
				public void init() throws ServletException {
					super.init();
					System.out.println("init method");
				}

				// 리퀘스트 요청시 마다 호출되는 service 메서드 최초 인스턴스 생성시 항상 메모리에 띄워져 있고
				// 리퀘스트 요청마다 각자의 service 스레드가 작업을 담당하여 리스폰스 한다.
				@Override
				protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

					System.out.println("service method");

					// 인증, 보안, 다국어, 공통 기능 처리하는 부분이 들어감감

					// 요청 URI 값에 따른 작업 분기 처리
					if(req.getRequestURI().equals("/hello") && req.getMethod().equals(HttpMethod.GET.name())) {

						// query string으로 넘어온 파라미터 name 값을 String으로 binding
						String name = req.getParameter("name");

						// helloController에게 파라미터를 넘겨주고 작업을 위임하고 처리한 결과를 받아오는 곳
						final String retrn = helloController.hello(name);

						// enum 클래스, 상수를 사용한 코드값 세팅
						resp.setStatus(HttpStatus.OK.value());
						resp.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE);
						// Response Body에 결과값을 보낸다
						resp.getWriter().println(retrn);

					} else if(req.getRequestURI().equals("/user")) {

					} else {
						// 설정되지 않은 URI가 들어오면 404에러
						resp.setStatus(HttpStatus.NOT_FOUND.value());
					}

				} // end of service

				// 컨테이너 종료시 호출되는 메서드 종료시 반드시 진행되야 하는 작업을 서술한다.
				@Override
				public void destroy() {
					super.destroy();
					System.out.println("destroy method");
				}

				// 리퀘스트 요청을 어느 servlet이 담당하게 될지 정하는 Mapping 추가
			}).addMapping("/*");

		});// end of webServer

		// 웹서버 작동 시작
		webServer.start();

		try {

			// 웹서버 종료시 destroy 메서드 실행되는지 확인 하기 위해
			// 웹서버 작동 후 10초 뒤에 웹서버 종료 메서드 호출
			Thread.sleep(10000);
			webServer.stop();

		} catch (InterruptedException e) {

			System.out.println(e);

		}

	} // end of main

} // end of class
package tobyspring.helloboot;

public class HelloServletController {

	public String hello(String name){
		return "Hello " + name;
	}

}

https://victorydntmd.tistory.com/154

 

[JSP/Servlet] Servlet 생명주기 ( Life Cycle )

1. Servlet 생명 주기 ( Life Cycle )클라이언트가 Servlet에 요청을 하면, Servlet은 바로 호출이 되지 않습니다.Servlet은 객체를 생성하고 초기화 작업을 거친 후, 요청을 처리하는 생명 주기를 갖고 있습

victorydntmd.tistory.com

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함