728x90
스프링 부트는 지금까지 고민한 문제를 깔끔하게 해결해 준다.
- 내장 톰캣을 사용해서 빌드와 배포를 편리하게 한다.
- 빌드시 하나의 Jar를 사용하면서, 동시에 Fat Jar 문제도 해결한다.
- 지금까지 진행한 내장 톰캣 서버를 실행하기 위한 복잡한 과정을 모두 자동으로 처리한다.
프로젝트 생성
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.2'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'hello'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
- 스프링 부트를 사용하면 라이브러리 뒤에 버전 정보가 없는 것을 확인할 수 있다.
- 스프링 부트는 현재 부트 버전에 가장 적절한 외부 라이브러리 버전을 자동으로 선택해준다. (이 부분에 대한 자세한 내용은 뒤에서 다룬다.)
HelloController
@RestController
public class HelloController {
@GetMapping("hello-spring")
public String hell(){
System.out.println("HelloController.hell");
return "hello spring!";
}
}
내장 톰켓 의존성 확인


- 라이브러리 의존관계를 따라가보면 내장 톰캣( tomcat-embed-core )이 포함된 것을 확인할 수 있다.
실행 과정
@SpringBootApplication
public class BootApplication {
public static void main(String[] args) {
SpringApplication.run(BootApplication.class, args);
}
}
- 스프링 부트를 실행할 때는 자바 main() 메서드에서 SpringApplication.run() 을 호출해주면 된다.
- 여기에 메인 설정 정보를 넘겨주는데, 보통 @SpringBootApplication 애노테이션이 있는 현재 클래스를 지정해주면 된다.
- 참고로 현재 클래스에는 @SpringBootApplication 애노테이션이 있는데, 이 애노테이션 안에는 컴포넌트 스캔을 포함한 여러 기능이 설정되어 있다. 기본 설정은 현재 패키지와 그 하위 패키지 모두를 컴포넌트 스캔한다.
"SpringApplication.run(BootApplication.class, args);" 한 줄에 코드에 수많은 일들이 동작하지만 핵심은 크게 2가지이다.
스프링 컨테이너를 생성한다.
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContextFactory
private ConfigurableApplicationContext createContext() {
if (!AotDetector.useGeneratedArtifacts()) {
return new AnnotationConfigServletWebServerApplicationContext();
}
return new ServletWebServerApplicationContext();
}
- new AnnotationConfigServletWebServerApplicationContext() 이 부분이 바로 스프링 부트가 생성하는 스프링 컨테이너이다.
- 이름 그대로 애노테이션 기반 설정이 가능하고, 서블릿 웹 서버를 지원하는 스프링 컨테이너이다.
WAS(내장 톰캣)를 생성한다
org.springframework.boot.web.embedded.tomcat.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);
}
- Tomcat tomcat = new Tomcat() 으로 내장 톰캣을 생성한다.
스프링 부트도 우리가 앞서 내장 톰캣에서 진행했던 것과 동일한 방식으로 스프링 컨테이너를 만들고, 내장 톰캣을 생성하고 그 둘을 연결하는 과정을 진행한다.
참고
스프링 부트는 너무 큰 라이브러리이기 때문에 스프링 부트를 이해하기 위해 모든 코드를 하나하나 파보는 것은 추천하지 않는다.
스프링 부트가 어떤 식으로 동작하는지 개념을 이해하고, 꼭 필요한 부분의 코드를 확인하자.
빌드와 배포
jar 빌드
./gradlew clean build
build/libs/boot-0.0.1-SNAPSHOT.jar 실행
java -jar boot-0.0.1-SNAPSHOT.jar
스프링 부트 jar 분석
boot-0.0.1-SNAPSHOT.jar 파일 크기를 보면 대략 18M 정도 된다. 참고로 버전에 따라서 용량은 변할 수 있다.
FatJar과 비슷한 방식으로 만들어진 것으로 생각되니 jarv파일 압축을 풀어보자
jar 압축 풀기
jar -xvf boot-0.0.1-SNAPSHOT.jar
JAR를 푼 결과

- JAR를 푼 결과를 보면 Fat Jar가 아니라 처음보는 새로운 구조로 만들어져 있다.
- 심지어 jar 내부에 jar를 담아서 인식하는 것이 불가능한데, jar가 포함되어 있고, 인식까지 되었다.
참고
빌드 결과를 보면 boot-0.0.1-SNAPSHOT-plain.jar 파일도 보이는데, 이것은 우리가 개발한 코드만 순수한 jar로 빌드한 것이다. 무시하면 된다.
728x90
'스프링 부트(핵심 원리와 활용)' 카테고리의 다른 글
| Ch03. 스프링 부트 스타터와 라이브러리 관리 - 라이브러리 직접 관리 (0) | 2023.03.07 |
|---|---|
| Ch02. 스프링 부트와 내장 톰캣 - 스프링 부트 실행 가능 Jar (0) | 2023.03.05 |
| Ch02. 스프링 부트와 내장 톰캣 - 편리한 부트 클래스 만들기 (0) | 2023.03.05 |
| Ch02. 스프링 부트와 내장 톰캣 - 내장 톰캣 (0) | 2023.03.03 |
| Ch02. 스프링 부트와 내장 톰캣 - WAR 배포 방식의 단점 (0) | 2023.03.03 |