1. 소개
이 예제에서는 mvn spring-boot : run 명령을 통해 Spring Boot 웹 애플리케이션을 시작하는 것과 java -jar 명령을 통해 jar / war 패키지로 컴파일 한 후 실행하는 것의 차이점을 살펴 봅니다.
여기서 Spring Boot 리 패키지 목표 의 구성에 이미 익숙하다고 가정 해 보겠습니다 . 이 주제에 대한 자세한 내용은 Create a Fat Jar App with Spring Boot를 참조하십시오 .
2. 스프링 부트 메이븐 플러그인
Spring Boot 애플리케이션을 작성할 때 Spring Boot Maven 플러그인 은 코드를 빌드, 테스트 및 패키징하는 데 권장되는 도구입니다.
이 플러그인은 다음과 같은 많은 편리한 기능과 함께 제공됩니다.
- 우리를 위해 올바른 의존성 버전을 해결합니다.
- 실행 가능한 단일 fat jar / war에 모든 의존성 (필요한 경우 임베디드 애플리케이션 서버 포함)을 패키지 할 수 있으며 다음 작업도 수행합니다.
- 클래스 경로 구성을 관리하므로 java -jar 명령 에서 긴 -cp 옵션을 건너 뛸 수 있습니다.
- 이제 패키지 내부에 중첩 된 모든 외부 jar 라이브러리를 찾아로드 하는 사용자 정의 ClassLoader 를 구현 합니다.
- 자동으로 main () 메소드를 찾아 매니페스트에서 구성하므로 java -jar 명령 에서 기본 클래스를 지정할 필요가 없습니다.
3. Maven으로 분해 된 형태로 코드 실행
웹 애플리케이션을 작업 할 때 Spring Boot Maven 플러그인 의 또 다른 흥미로운 기능인 임베디드 애플리케이션 서버에 웹 애플리케이션을 자동으로 배포하는 기능을 활용할 수 있습니다 .
플러그인에 Tomcat을 사용하여 코드를 실행한다는 것을 알리려면 의존성이 하나만 필요합니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
이제 프로젝트 루트 폴더에서 mvn spring-boot : run 명령을 실행할 때 플러그인은 pom 구성을 읽고 웹 애플리케이션 컨테이너가 필요하다는 것을 이해합니다.
실행중인 실행 MVN 스프링 부팅을 명령 트리거를 아파치 톰캣의 다운로드와 톰캣의 시작을 초기화합니다.
해 보자:
$ mvn spring-boot:run
...
...
[INFO] --------------------< com.baeldung:spring-boot-ops >--------------------
[INFO] Building spring-boot-ops 0.0.1-SNAPSHOT
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] >>> spring-boot-maven-plugin:2.1.3.RELEASE:run (default-cli) > test-compile @ spring-boot-ops >>>
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/9.0.16/tomcat-embed-core-9.0.16.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/9.0.16/tomcat-embed-core-9.0.16.pom (1.8 kB at 2.8 kB/s)
...
...
[INFO] --- spring-boot-maven-plugin:2.1.3.RELEASE:run (default-cli) @ spring-boot-ops ---
...
...
11:33:36.648 [main] INFO o.a.catalina.core.StandardService - Starting service [Tomcat]
11:33:36.649 [main] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.16]
...
...
11:33:36.952 [main] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
...
...
11:33:48.223 [main] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
11:33:48.289 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path ''
11:33:48.292 [main] INFO org.baeldung.boot.Application - Started Application in 22.454 seconds (JVM running for 37.692)
로그에 'Started Application'이 포함 된 줄이 표시되면 http : // localhost : 8080 / 주소에서 브라우저를 통해 웹 애플리케이션을 쿼리 할 준비가 된 것입니다.
4. 독립 실행 형 패키지 애플리케이션으로 코드 실행
개발 단계를 통과하고 애플리케이션을 프로덕션 단계로 진행하려면 애플리케이션을 패키징해야합니다.
불행히도 jar 패키지 로 작업하는 경우 기본 Maven 패키지 목표에는 외부 의존성이 포함되지 않습니다.
이것은 우리가 더 큰 프로젝트에서 라이브러리로만 사용할 수 있음을 의미합니다.
이러한 제한을 피하려면 Maven Spring Boot 플러그인 리 패키지 목표를 활용하여 jar / war를 독립형 애플리케이션으로 실행해야합니다.
4.1. 구성
일반적으로 빌드 플러그인 만 구성하면됩니다.
<build>
<plugins>
...
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
...
</plugins>
</build>
그러나 예제 프로젝트에는 둘 이상의 기본 클래스가 포함되어 있으므로 플러그인을 구성하여 실행할 클래스를 Java에 알려야합니다.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<configuration>
<mainClass>com.baeldung.webjar.WebjarsdemoApplication</mainClass>
</configuration>
</execution>
</executions>
</plugin>
또는 start-class 속성 을 설정하여 :
<properties>
<start-class>com.baeldung.webjar.WebjarsdemoApplication</start-class>
</properties>
4.2. 응용 프로그램 실행
이제 두 가지 간단한 명령으로 예제 전쟁을 실행할 수 있습니다.
$ mvn clean package spring-boot:repackage
$ java -jar target/spring-boot-ops.war
jar 파일을 실행하는 방법에 대한 자세한 내용은 Run JAR Application With Command Line Arguments 문서에서 찾을 수 있습니다 .
4.3. 전쟁 파일 내부
위에서 언급 한 명령이 전체 서버 애플리케이션을 실행하는 방법을 더 잘 이해하기 위해 spring-boot-ops.war을 살펴볼 수 있습니다.
압축을 풀고 내부를 들여다 보면 일반적인 용의자를 찾습니다.
- META-INF , 자동 생성 된 MANIFEST.MF 포함
- WEB-INF / classes , 컴파일 된 클래스 포함
- WEB-INF / lib- 전쟁 의존성 및 임베디드 Tomcat jar 파일을 보유합니다.
팻 패키지 구성에 특정한 폴더가 있기 때문에 그게 전부는 아닙니다.
- WEB-INF / lib-provided , 임베디드 실행시 필요하지만 배포시 필요하지 않은 외부 라이브러리 포함
- org / springframework / boot / loader- Spring Boot 커스텀 클래스 로더를 보유합니다.이 라이브러리는 외부 의존성을로드하고 런타임에서 액세스 할 수 있도록합니다.
4.4. 전쟁 매니페스트 내부
앞서 언급했듯이 Maven Spring Boot 플러그인은 기본 클래스를 찾고 java 명령 을 실행하는 데 필요한 구성을 생성합니다 .
결과 MANIFEST.MF 에는 몇 가지 추가 행이 있습니다.
Start-Class: com.baeldung.webjar.WebjarsdemoApplication
Main-Class: org.springframework.boot.loader.WarLauncher
특히 마지막 것은 사용할 Spring Boot 클래스 로더 런처를 지정하는 것을 볼 수 있습니다.
4.5. Jar 파일 내부
기본 패키징 전략으로 인해 전쟁 패키징 시나리오는 Spring Boot Maven Plugin 사용 여부에 관계없이 크게 다르지 않습니다.
플러그인의 장점을 더 잘 이해하기 위해 pom 패키징 구성을 jar로 변경하고 mvn clean package를 다시 실행할 수 있습니다.
이제 우리의 fat jar가 이전 war 파일과 약간 다르게 구성되어 있음을 확인할 수 있습니다.
- 모든 클래스 및 리소스 폴더는 이제 BOOT-INF / classes 아래에 있습니다.
- BOOT-INF / lib 는 모든 외부 라이브러리를 보유합니다.
플러그인이 없으면 lib 폴더는 존재하지 않으며 BOOT-INF / classes 의 모든 내용은 패키지의 루트에 있습니다.
4.6. Jar Manifest 내부
또한 매니페스트. MF는 다음과 같은 추가 라인을 특징으로 변경되었습니다.
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.1.3.RELEASE
Main-Class: org.springframework.boot.loader.JarLauncher
Spring-Boot-Classes 와 Spring-Boot-Lib 는 클래스 로더가 클래스와 외부 라이브러리를 찾을 위치를 알려주기 때문에 특히 흥미 롭습니다.
5. 선택 방법
도구를 분석 할 때 이러한 도구가 만들어진 목적을 고려하는 것이 중요합니다. 개발을 용이하게하고 싶습니까? 아니면 원활한 배포와 이동성을 보장하고 싶습니까? 이 선택의 영향을 가장 많이받는 단계를 살펴 보겠습니다.
5.1. 개발
개발자로서 우리는 종종 코드를 로컬에서 실행하기 위해 환경을 설정하는 데 많은 시간을 할애하지 않고 코딩에 대부분의 시간을 소비합니다. 간단한 응용 프로그램에서는 일반적으로 문제가되지 않습니다. 그러나 더 복잡한 프로젝트의 경우 환경 변수를 설정하고 서버를 시작하고 데이터베이스를 채워야 할 수 있습니다.
애플리케이션을 실행할 때마다 올바른 환경을 구성하는 것은 매우 비실용적입니다 . 특히 두 개 이상의 서비스를 동시에 실행 해야하는 경우 더욱 그렇습니다.
Maven으로 코드를 실행하면 도움이됩니다. 이미 전체 코드베이스를 로컬로 체크 아웃 했으므로 pom 구성 및 리소스 파일을 활용할 수 있습니다. 환경 변수를 설정하고, 메모리 내 데이터베이스를 생성하고, 올바른 서버 버전을 다운로드하고 하나의 명령으로 애플리케이션을 배포 할 수도 있습니다.
각 모듈에 다른 변수와 서버 버전이 필요한 다중 모듈 코드베이스에서도 Maven 프로필을 통해 적절한 환경을 쉽게 실행할 수 있습니다.
5.2. 생산
우리가 생산으로 더 많이 이동할수록 대화는 안정성과 Security으로 더 많이 이동합니다. 그렇기 때문에 개발 기계에 사용 된 프로세스를 실제 고객이있는 서버에 적용 할 수 없습니다.
이 단계에서 Maven을 통해 코드를 실행하는 것은 여러 가지 이유로 나쁜 습관입니다.
- 먼저 Maven을 설치해야합니다.
- 그런 다음 코드를 컴파일해야하기 때문에 전체 JDK (Java Development Kit)가 필요합니다.
- 다음으로 코드베이스를 서버에 복사하고 모든 독점 코드를 일반 텍스트로 남겨 두어야합니다.
- MVN 명령은 수명주기의 모든 단계를 실행해야한다 (찾기 소스, 컴파일 및 실행)
- 이전 포인트 덕분에 우리는 CPU와 클라우드 서버의 경우 돈을 낭비했습니다.
- Maven은 각각 메모리를 사용하는 여러 Java 프로세스를 생성합니다 (기본적으로 각 프로세스는 상위 프로세스와 동일한 메모리 양을 사용함).
- 마지막으로 배포 할 서버가 여러 대인 경우 위의 모든 작업이 각 서버에서 반복됩니다.
이것은 응용 프로그램을 패키지로 배송하는 것이 생산에 더 실용적인 이유 입니다.
6. 결론
이 예제에서는 Maven과 java -jar 명령을 통해 코드를 실행하는 것의 차이점을 살펴 보았습니다 . 또한 몇 가지 실제 사례 시나리오에 대한 간략한 개요를 실행했습니다.
- https://docs.spring.io/spring-framework/docs/current/reference/html
- https://www.baeldung.com/spring-boot-run-maven-vs-executable-jar
'Java' 카테고리의 다른 글
Spring과 Spring Boot의 비교 (0) | 2021.04.22 |
---|---|
블레이드 – 완벽한 사용방법(예제) 북 (0) | 2021.04.21 |
Morphia 소개 – MongoDB 용 Java ODM (0) | 2021.04.21 |
Spring Cloud App Starter 사용 (0) | 2021.04.21 |
RAML 소개 – RESTful API 모델링 언어 (0) | 2021.04.21 |