[Spring Boot Tutorial] 14. build 환경별 profile 적용하기

2020. 6. 29. 17:30Spring/Spring Boot Tutorial

반응형

웹 애플리케이션을 배포할 때, 서버 환경별로 값을 달리해야 하는 값들이 있을 수 있습니다.
예를들면, 로컬에서 테스트하는 database 접속 정보와 실 서버에서 이용하는 database 접속 정보가 다를 수 있을 것이고.
그 외에도 특정 폴더 경로의 절대경로의 경우에도. 리눅스 기반 서버와 Windows 서버의 폴더구조가 다르기에 값을 달리 작성해야하는 필요가 생깁니다.

[Spring Boot] 프로퍼티 파일(yml) 여러개 설정하기 포스팅에서는 긴 프로퍼티 파일을 성질에 따라 쪼개어, 2개 이상의 프로퍼티 파일을 읽어들이는 방법을 알아보았다면,

이번 시간에는 서버 환경별로 활성화 시킬 프로퍼티 파일을 선택하여 배포할 수 있도록 하는 방법을 배워볼 것입니다.

  1. 프로파일 폴더 구조
  2. 프로파일별 프로퍼티 설정
  3. pom.xml 설정

1. 프로파일 폴더 구조

99

프로파일 별로 프로퍼티 파일을 분리하지 않은 기존의 resources 폴더 구조입니다.
src/main/resources 폴더 내에 application.yml, demo.yml 프로퍼티 파일이 들어있습니다.

설정하는 프로파일에 따라 읽어들일 프로퍼티를 달리 하기 위해 폴더를 생성해봅시다.

resources 폴더 안에 profile 폴더를 만들고, 만들고자 하는 프로파일명을 딴 폴더 이름을 추가합니다.
저는 로컬(local), 운영(prod) 프로파일을 만들고자 하기에, profile 폴더 하위에 local, prod 폴더를 생성하였습니다.

그리고, 각 프로퍼티 파일들을 local, prod 폴더에 복사한 후, 기존의 파일은 삭제해 줍니다.

98

그러면 위와 같은 폴더구조가 형성됩니다.

각 프로파일 폴더 내에 들어있는 yml 파일은 각 빌드 환경에 맞는 설정으로 변경해 주면 됩니다.


2. 프로파일별 프로퍼티 설정

2-1) local

spring:
  application:
    name: demo
  profiles:
    active: local

    ... (생략) ...

application.yml 中 일부

로컬환경의 spring.profiles.active 값은 local입니다.

demo:
  api: /api/v1
  url: 'http://localhost:${server.port}'
  version: '@project.version@'

demo.yml


2-2) prod

spring:
  application:
    name: demo
  profiles:
    active: prod

    ... (생략) ...

application.yml 中 일부

운영환경의 spring.profiles.active 값은 prod입니다.

demo:
  api: /api/v1
  url: https://demo-old.jiniworld.me
  version: '@project.version@'

demo.yml

운영환경에서는 도메인 주소를 url로 설정했습니다.


@Bean
public OpenAPI openAPI(@Value("${demo.version}") String appVersion,
    @Value("${demo.url}") String url, @Value("${spring.profiles.active}") String active) {
  Info info = new Info().title("Demo API - " + active).version(appVersion)
      .description("Spring Boot를 이용한 Demo 웹 애플리케이션 API입니다.")
      .termsOfService("http://swagger.io/terms/")
      .contact(new Contact().name("jini").url("https://blog.jiniworld.me/").email("jini@jiniworld.me"))
      .license(new License().name("Apache License Version 2.0").url("http://www.apache.org/licenses/LICENSE-2.0"));

  List<Server> servers = Arrays.asList(new Server().url(url).description("demo (" + active +")"));
  return new OpenAPI()
      .components(new Components())
      .info(info)
      .servers(servers);
}

demo.yml 에 설정했던 demo.url 을 가져와서 OpenAPI 3 api의 서버를 설정하도록 했습니다.
※ OpenAPI 3 에 대해 알고 싶다면 이전 포스팅인 [Spring Boot Tutorial] 13. OpenAPI 3.0를 이용한 REST API 문서 만들기 with Swagger 글을 참고해주세요.


3. pom.xml 설정

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <java.version>1.8</java.version>
  <springdoc.openapi.version>1.4.1</springdoc.openapi.version>
</properties>

<profiles>
  <profile>
    <id>local</id>
    <properties>
      <env>local</env>
      <maven.test.skip>true</maven.test.skip>
    </properties>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
  </profile>
  <profile>
    <id>prod</id>
    <properties>
      <env>prod</env>
    </properties>
  </profile>
</profiles>

<project> 태그 하위(<dependencies> 태그와 동등한 레벨)에 <profile> 태그를 추가합니다.
프로파일 설정을 별도로 하지 않을 경우 기본적으로 활성화 시킬 프로파일에 activeByDefaulttrue 설정을 합니다.

활성화된 프로파일은 <properties> 내에 있는 태그들을 프로퍼티로 가질 수 있습니다.
프로파일 내의 properties은 해당 프로파일이 활성화 되었을 경우에면 properties로 설정됩니다.
(공통적으로 이용할 프로퍼티는 ln 1~6 안에 설정하고, 프로파일 별로 설정할 프로퍼티는 ln 11~14, ln 21~23과 같이 profile 내에 설정합니다.)

우리는 <profile> 내에 정의한 프로퍼티인 <env> 를 이용하여 build시 특정 프로파일을 포함시키거나 제외시킬 것입니다.


환경별로 빌드를 달리하기 위해 build 정보를 변경합니다.
<project> 태그 하위(<dependencies> 태그와 동등한 레벨)에 위치한 <build> 태그를 수정해 봅시다.

<build>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
      <excludes>
        <exclude>profile/**/**</exclude>
      </excludes>
    </resource>
    <resource>
      <directory>src/main/resources/profile/${env}</directory>
      <filtering>true</filtering>
    </resource>
  </resources>

  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
        <finalName>demo</finalName>
      </configuration>
    </plugin>
  </plugins>
</build>

resources 내의 정적 파일 중 profile 하위 파일은 먼저 제외(exclude) 시키고,
활성화된 프로파일의 id가 들어있는 ${env} 폴더를 포함시킵니다.


4. 테스트

4-1) local

local 프로파일을 active 해봅시다.

100

로그에 local 프로파일이 active 되었다고 출력되었습니다.

103

Swagger 화면입니다. local 프로파일에 설정했던 spring.profile.activedemo.url 값이 잘 출력되는 것을 확인할 수 있습니다.


mvnw 명령어로 local 프로파일로 패키징 합니다.

D:\jini_box\java\workspace-java3\demo>mvnw clean package -P local
Found "D:\jini_box\java\workspace-java3\demo\.mvn\wrapper\maven-wrapper.jar"
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------------< me.jiniworld:demo >--------------------------
[INFO] Building demo 1.0.11
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ demo ---
[INFO] Deleting D:\jini_box\java\workspace-java3\demo\target
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 18 resources
[INFO] Copying 2 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 35 source files to D:\jini_box\java\workspace-java3\demo\target\classes
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ demo ---
[INFO] Not copying test resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ demo ---
[INFO] Not compiling test sources
[INFO]
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ demo ---
[INFO] Tests are skipped.
[INFO]
[INFO] --- maven-jar-plugin:3.1.2:jar (default-jar) @ demo ---
[INFO] Building jar: D:\jini_box\java\workspace-java3\demo\target\demo-1.0.11.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.1.8.RELEASE:repackage (repackage) @ demo ---
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  9.512 s
[INFO] Finished at: 2020-06-29T17:15:55+09:00
[INFO] ------------------------------------------------------------------------

4-2) prod

local 프로파일을 active 해봅시다.

101

로그에 prod 프로파일이 active 되었다고 출력되었습니다.

102

Swagger 화면입니다. prod 프로파일에 설정했던 spring.profile.activedemo.url 값이 잘 출력되는 것을 확인할 수 있습니다.


mvnw 명령어로 prod 프로파일로 패키징 합니다.

D:\jini_box\java\workspace-java3\demo>mvnw clean package -P prod
Found "D:\jini_box\java\workspace-java3\demo\.mvn\wrapper\maven-wrapper.jar"
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------------< me.jiniworld:demo >--------------------------
[INFO] Building demo 1.0.11
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ demo ---
[INFO] Deleting D:\jini_box\java\workspace-java3\demo\target
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 18 resources
[INFO] Copying 2 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 35 source files to D:\jini_box\java\workspace-java3\demo\target\classes
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\jini_box\java\workspace-java3\demo\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to D:\jini_box\java\workspace-java3\demo\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ demo ---
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running me.jiniworld.demo.DemoApplicationTests
17:16:59.523 [main] DEBUG org.springframework.test.context.junit4.SpringJUnit4ClassRunner - SpringJUnit4ClassRunner constructor called with [class me.jiniworld.demo.DemoApplicationTests]
17:16:59.531 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating CacheAwareContextLoaderDelegate from class [org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate]
17:16:59.543 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating BootstrapContext using constructor [public org.springframework.test.context.support.DefaultBootstrapContext(java.lang.Class,org.springframework.test.context.CacheAwareContextLoaderDelegate)]
17:16:59.574 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating TestContextBootstrapper for test class [me.jiniworld.demo.DemoApplicationTests] from class [org.springframework.boot.test.context.SpringBootTestContextBootstrapper]
17:16:59.599 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [me.jiniworld.demo.DemoApplicationTests], using SpringBootContextLoader
17:16:59.606 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [me.jiniworld.demo.DemoApplicationTests]: class path resource [me/jiniworld/demo/DemoApplicationTests-context.xml] does not exist
17:16:59.607 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [me.jiniworld.demo.DemoApplicationTests]: class path resource [me/jiniworld/demo/DemoApplicationTestsContext.groovy] does not exist
17:16:59.607 [main] INFO org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [me.jiniworld.demo.DemoApplicationTests]: no resource found for suffixes {-context.xml, Context.groovy}.
17:16:59.608 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils - Could not detect default configuration classes for test class [me.jiniworld.demo.DemoApplicationTests]: DemoApplicationTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
17:16:59.696 [main] DEBUG org.springframework.test.context.support.ActiveProfilesUtils - Could not find an 'annotation declaring class' for annotation type [org.springframework.test.context.ActiveProfiles] and class [me.jiniworld.demo.DemoApplicationTests]
17:16:59.802 [main] DEBUG org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider - Identified candidate component class: file [D:\jini_box\java\workspace-java3\demo\target\classes\me\jiniworld\demo\DemoApplication.class]
17:16:59.804 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Found @SpringBootConfiguration me.jiniworld.demo.DemoApplication for test class me.jiniworld.demo.DemoApplicationTests
17:16:59.925 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - @TestExecutionListeners is not present for class [me.jiniworld.demo.DemoApplicationTests]: using defaults.
17:16:59.926 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
17:16:59.970 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@2d3379b4, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@30c15d8b, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@5e0e82ae, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@6771beb3, org.springframework.test.context.support.DirtiesContextTestExecutionListener@51399530, org.springframework.test.context.transaction.TransactionalTestExecutionListener@6b2ea799, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@411f53a0, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@2b71e916, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@36fc695d, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@28701274, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@13c9d689, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@3754a4bf]
17:16:59.973 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [me.jiniworld.demo.DemoApplicationTests]
17:16:59.974 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [me.jiniworld.demo.DemoApplicationTests]
17:16:59.976 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [me.jiniworld.demo.DemoApplicationTests]
17:16:59.976 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [me.jiniworld.demo.DemoApplicationTests]
17:16:59.977 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [me.jiniworld.demo.DemoApplicationTests]
17:16:59.977 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [me.jiniworld.demo.DemoApplicationTests]
17:16:59.987 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - Before test class: context [DefaultTestContext@815b41f testClass = DemoApplicationTests, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@5542c4ed testClass = DemoApplicationTests, locations = '{}', classes = '{class me.jiniworld.demo.DemoApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@481a15ff, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@545997b1, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@24b1d79b, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@8b87145], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true]], class annotated with @DirtiesContext [false] with mode [null].
17:16:59.989 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [me.jiniworld.demo.DemoApplicationTests]
17:16:59.989 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [me.jiniworld.demo.DemoApplicationTests]
17:17:00.035 [main] DEBUG org.springframework.test.context.support.TestPropertySourceUtils - Adding inlined properties to environment: {spring.jmx.enabled=false, org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true, server.port=-1}
   _
 _| |___ _____ ___
| . | -_|     | . |
|___|___|_|_|_|___|

2020-06-29 17:17:00.699 - INFO [                  main] me.jiniworld.demo.DemoApplicationTests   : Starting DemoApplicationTests on jini with PID 6612 (started by jini in D:\jini_box\java\workspace-java3\demo)
2020-06-29 17:17:00.700 - INFO [                  main] me.jiniworld.demo.DemoApplicationTests   : The following profiles are active: prod
2020-06-29 17:17:00.961 -DEBUG [                  main] o.s.w.c.s.GenericWebApplicationContext   : Refreshing org.springframework.web.context.support.GenericWebApplicationContext@14fa86ae
2020-06-29 17:17:01.897 - INFO [                  main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
2020-06-29 17:17:01.997 - INFO [                  main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 87ms. Found 3 repository interfaces.
2020-06-29 17:17:02.015 - WARN [                  main] o.m.s.mapper.ClassPathMapperScanner      : Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.
2020-06-29 17:17:02.016 - WARN [                  main] o.m.s.mapper.ClassPathMapperScanner      : Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.
2020-06-29 17:17:02.913 - INFO [                  main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$7f0c0d77] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-06-29 17:17:02.957 - INFO [                  main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.hateoas.config.HateoasConfiguration' of type [org.springframework.hateoas.config.HateoasConfiguration$$EnhancerBySpringCGLIB$$fe8c5aa9] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-06-29 17:17:03.238 - INFO [                  main] com.zaxxer.hikari.HikariDataSource       : pool-jiniworld - Starting...
2020-06-29 17:17:04.401 - INFO [                  main] com.zaxxer.hikari.HikariDataSource       : pool-jiniworld - Start completed.
2020-06-29 17:17:04.491 - INFO [                  main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
        name: default
        ...]
2020-06-29 17:17:04.626 - INFO [                  main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.3.11.Final}
2020-06-29 17:17:04.629 - INFO [                  main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2020-06-29 17:17:04.908 - INFO [                  main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
2020-06-29 17:17:05.122 - INFO [                  main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
... (생략) ...
2020-06-29 17:17:10.521 - INFO [              Thread-4] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2020-06-29 17:17:10.523 - INFO [              Thread-4] com.zaxxer.hikari.HikariDataSource       : pool-jiniworld - Shutdown initiated...
2020-06-29 17:17:10.547 - INFO [              Thread-4] com.zaxxer.hikari.HikariDataSource       : pool-jiniworld - Shutdown completed.
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- maven-jar-plugin:3.1.2:jar (default-jar) @ demo ---
[INFO] Building jar: D:\jini_box\java\workspace-java3\demo\target\demo-1.0.11.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.1.8.RELEASE:repackage (repackage) @ demo ---
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  23.574 s
[INFO] Finished at: 2020-06-29T17:17:12+09:00
[INFO] ------------------------------------------------------------------------

운영 환경의 경우 maven.test 를 스킵하지 않기 때문에 TEST 과정도 거칩니다.


GitHub에서 demo 프로젝트를 다운받아 볼 수 있습니다.

728x90
반응형