SPRING/Spring Boot

[SpringBoot] SpringBoot 웹환경 구성 원리

IT록흐 2023. 4. 27. 11:26
반응형

 

 

지난 포스팅에서는 Spring Boot 클래스를 직접 만들어보았다.

 

 

 

[SpringBoot] 내장톰캣에서 Spring Boot클래스 만들기

[SpringBoot] Main클래스에서 내장톰캣 실행시키기 [SpringBoot] 외장톰캣에서 SpringMVC 구현하기 [SpringBoot] 외장톰캣으로 WAS 띄우기 with IntelliJ(무료버전) SpringBoot는 내장톰캣을 사용한다. SpringBoot가 내장

lordofkangs.tistory.com

 

 

 

 

 

MySpringBootMain 클래스는 Main클래스로 MySpringApplication 클래스를 호출하여 실행한다. MySpringApplication 클래스는 스프링컨테이너, DispatcherServlet, 내장톰캣을 생성 및 설정을 담당하는 클래스이다.

 

지난 포스팅에서는 위 과정을 모두 직접 코드로 구현해보았다. 그러나 우리가 직접 코드로 구현할 필요는 없다. 스프링부트가 이미 위 과정을 모두 자동화 해놓았기 때문이다. 우리는 그저 스프링부트로 프로젝트만 생성하면 된다. 

 

 

 

먼저 간단히 프로젝트 하나를 생성한다.

 

 

1. DemoApplication

package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args); // DemoApplication 클래스 파라미터로 넘기기
	}
}

 

프로젝트를 IDE에서 열면 DemoApplication 클래스가 자동으로 생성되어 있음을 확인할 수 있다.

이 클래스는 Main함수를 갖고 있는데, 웹서비스를 마치 JAVA프로그램처럼 실행시킨다는 SpringBoot의 철학이다.  

 

DemoApplication클래스는 @SpringBootApplication 어노테이션을 갖는 클래스이다. @SpringBootApplication은 컴포넌트스캔 기능을 가지고 있어 하위디렉토리의 Bean을 자동으로 스프링컨테이너에 등록해준다. 고로, DemoApplication클래스가 Bean설정클래스인 것이다. 그러므로 스프링컨테이너에 DemoApplication을 등록해야 한다. SpringApplication클래스가 스프링컨테이너(IOC컨테이너)를 생성하므로, run메소드에 DemoApplication 클래스를 파라미터로 던져준다.

 

2. SpringApplication

 

SpringApplication은 Spring 웹서비스 환경을 구성하는 클래스이다. 기본적으로 IOC컨테이너(ApplicationContext)내장톰캣을 구성한다. 디버깅을 해보자.

 

- IOC컨테이너(ApplicationContext) 생성

 

1) SpringApplication - run 메소드

public ConfigurableApplicationContext run(String... args) {			
            // 중략...
			context = createApplicationContext();	//IOC컨테이너 생성
    		// 중략 ...            
}

 

2) SpringApplication - createApplicationContext 메소드 

protected ConfigurableApplicationContext createApplicationContext() {
	return this.applicationContextFactory.create(this.webApplicationType); // webApplicationType : SERVLET
}

IOC 컨테이너의 종류를 WebApplication으로 정한다. 

 

3) ServletWebServerApplicationContextFactory - createContext 메소드

class ServletWebServerApplicationContextFactory implements ApplicationContextFactory {

	// 중략....
	@Override
	public ConfigurableApplicationContext create(WebApplicationType webApplicationType) {
		return (webApplicationType != WebApplicationType.SERVLET) ? null : createContext(); //WebApplicationType이 SERVLET이므로 createContext() 실행
	}

	private ConfigurableApplicationContext createContext() {
		if (!AotDetector.useGeneratedArtifacts()) {
			return new ㅊ(); // IOC컨테이너 생성 ( ApplicationContext의 구현체 )
		}
		return new ServletWebServerApplicationContext();
	}

}

 

IOC컨테이너, 즉 ApplicationContext의 구현체로 AnnotationConfigServletWebServerApplicationContext 객체가 생성되는 코드이다. 이처럼 SpringBoot는 SpringApplication 클래스에서 run 메소드를 호출함으로써 웹에 맞는 IOC 컨테이너를 자동생성한다.

 

 

- 내장톰캣 생성

 

1) SpringApplication 

public ConfigurableApplicationContext run(String... args) {
	// 중략...
            refreshContext(context); 
            //중략...
}

protected void refresh(ConfigurableApplicationContext applicationContext) {
		applicationContext.refresh(); // 생성된 IOC컨테이너의 refresh메소드 호출
}

 

 

위에서 생성한 IOC컨테이너는 ServletWebServerApplicationContext 클래스의 자식클래스이다. 

 

run 메소드가 실행되면 ApplicationContext(IOC컨테이너)를 초기화하는 단계가 있다. 이때 ApplicationContext의 refresh 메소드를 호출하는데 ServletWebServerApplicationContext의 경우, 이 과정에서 내장톰캣을 생성한다.

 

 

2) AbstractApplicationContext 

@Override
public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
				// 중략....
				// Initialize other special beans in specific context subclasses.
				onRefresh();
               		 	// 중략...
		}              
}

 

AbstractApplicationContext는 ServletWebServerApplicationContext의 추상클래스이다. ServletWebServerApplicationContext는 OnRefresh()를 아래와 같이 재정의한다.

 

 

3) ServletWebServerApplicationContext

@Override
protected void onRefresh() {
		super.onRefresh();
		try {
			createWebServer(); //내장톰캣 생성
		}
		catch (Throwable ex) {
			throw new ApplicationContextException("Unable to start web server", ex);
		}
}

// 내장톰캣 생성 메소드
private void createWebServer() {	
			//중략...
			this.webServer = factory.getWebServer(getSelfInitializer()); // 웹서버생성 Factory로 톰캣 생성
			//중략...
}

 

ServletWebServerApplicationContext는 WebServer를 생성하는 Factory 객체를 통해 내장톰캣을 생성한다.

 

 

4) TomcatServletWebServerFactory 

@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
    if (this.disableMBeanRegistry) {
        Registry.disableRegistry();
    }
    Tomcat tomcat = new Tomcat(); // 톰캣 생성
    File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
    tomcat.setBaseDir(baseDir.getAbsolutePath());
    for (LifecycleListener listener : this.serverLifecycleListeners) {
        tomcat.getServer().addLifecycleListener(listener);
    }
    Connector connector = new Connector(this.protocol); // 커넥터 생성
    connector.setThrowOnFailure(true);
    tomcat.getService().addConnector(connector);
    customizeConnector(connector);
    tomcat.setConnector(connector); // 톰캣과 커넥터 연결
    tomcat.getHost().setAutoDeploy(false);
    configureEngine(tomcat.getEngine());
    for (Connector additionalConnector : this.additionalTomcatConnectors) {
        tomcat.getService().addConnector(additionalConnector);
    }
    prepareContext(tomcat.getHost(), initializers);
    return getTomcatWebServer(tomcat);
}

 

TomcatServletWebServerFactory에서 실질적으로 톰캣 객체를 생성하여 반환하는 코드를 확인할 수 있다.

 

 


 

 

SpringApplication 클래스에서 Spring 웹 서비스 환경 구성에 필요한 기본요소 2가지를 자동으로 생성해주는 것을 확인하였다. 

 

정리하면

 

DemoApplication은 Main클래스이다. 그리고 ComponentScan 기능을 가진 Spring Bean설정파일이다. Spring 웹환경은 SpringApplication이 생성하므로, run메소드에 Bean설정파일을 인수로 넘겨준다. SpringApplication은 넘겨받은 Bean설정클래스로 IOC컨테이너(ApplicationContext)를 생성하고 생성된 IOC컨테이너를 초기화(refresh)하는 과정에서 웹서버(내장톰캣) 환경도 구성이 된다. 

 

고로, SpringBoot는 단순 main메소드 실행 하나로, 웹서비스 환경 구성을 자동화한다.

 

 


 

참고자료

 

스프링 부트 - 핵심 원리와 활용 - 인프런 | 강의

실무에 필요한 스프링 부트는 이 강의 하나로 모두 정리해드립니다., - 강의 소개 | 인프런

www.inflearn.com

 

 

 

반응형