IntelliJ IDEA에서 Spring Boot 웹 프로젝트 생성하기

개요

Spring Boot는 최근 Java 진영에서 각광 받고 있는 간결하고 강력한 웹 프레임워크이다. 이름에서 드러나듯이 국내에서 가장 사랑 받는 Spring 프레임워크를 기반으로 한다. 경쟁자로 역시 뒤지지 않는 막강한 기능의 Dropwizard가 존재하지만 그리 친숙하지 않은 JAX-RS를 기반으로 하여 앞으로도 국내에서 많이 쓰이지는 않을 것으로 생각된다.(나는 작년 국내 모 영화 포탈 서비스의 일부를 JAX-RS 기반의 Jersey로 개발하며 상당한 생산성 향상을 경험한 적이 있다. 문제는 후에 담당한 운영 인력이 익숙치 않은 문법에 어려움을 겪었다고 한다.) 최근에는 소속한 회사의 REST API 백엔드 서비스를 Spring Boot로 개발하고 있는데 매번 그 편리함에 감탄하고 있다. 한편, IntelliJ IDEAEclipse를 압도하는 Java 진영 최강의 IDE로 군림하고 있다. IntelliJSpring Boot의 조합은 신세계라고 생각되어 본 글에서 간단히 프로젝트 생성 방법을 소개하고자 한다.

사전 설치 준비물

Spring Boot 프로젝트 생성

먼저 Spring Boot 프로젝트를 생성한다. JDK 8, IntelliJ IDEA 15가 이미 설치된 상태라고 가정하고 진행한다.

  • IntelliJ IDEA 실행 → Create New Project 클릭
  • 좌측 메뉴에서 Gradle 클릭 → Project SDK: 1.8 → Additional Libraries and Frameworks: Java 체크 → Next 클릭
  • GroupId: com.jsonobject 입력 → ArtifactId: spring-boot-example 입력 → Version: 0.0.1 입력 → Next 클릭
  • Use auto-import 체크 → Create directories for empty content roots automatically 체크 → Use default gradle wrapper (recommended) 선택 → Gradle JVM: 1.8 선택→ Next 클릭
  • Project name: spring-boot-example 입력 → Project location: D:\Projects\spring-boot-example 입력 → Finish 클릭
  • 위 방법 외에 Spring Initializr를 사용하여 프로젝트를 생성할 수도 있다. 이 방법을 추천한다.

build.gradle 작성

프로젝트 생성을 완료하면 /build.gradle 파일이 생성되어 있다. 아래 내용으로 교체하자. 프로젝트 생성을 위한 최소한의 구성으로 실제 엔터프라이즈 급의 프로젝트를 생성하려면 테스트, 배포 태스크 등 훨씬 복잡한 내용이 추가되어야 한다.

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'eclipse'
apply plugin: 'idea'

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    maven {
        url("https://plugins.gradle.org/m2/")
    }
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.9'
}

jar {
    baseName = 'spring-boot-example'
    version = '0.0.1'
}

buildscript {
    repositories {
        maven {
            url("https://plugins.gradle.org/m2/")
        }
    }
    dependencies {
        classpath group: 'org.springframework.boot', name: 'spring-boot-gradle-plugin', version: '1.5.6.RELEASE'
    }
}

plugins {
    id 'org.springframework.boot' version '1.5.6.RELEASE'
}

bootRepackage {
    executable = true
}

dependencies {
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-web'
}
  • Spring Boot(1.3.5)는 기본적으로 Embedded Tomcat(8.0.33)을 컨테이너로 사용한다. 전통적으로 컨테이너 위에서 배포되어 작동하는 방식이 아니라 빌드된 .JAR를 실행하면 내장된 컨테이너를 실행하여 애플리케이션을 작동시킨다. 이런 특징은 번거로운 배포 절차와 컨테이너에 대한 애플리케이션의 종속성을 최소화 시켜준다.
  • 리눅스 운영 환경에서 init.d의 서비스 형태로 애플리케이션을 실행하려면 plugins, bootRepackage 설정은 필수이다.

.gitignore 작성

Git으로 소스 코드를 관리할 경우 IntelliJ IDEAGradle이 생성하는 파일까지 관리 대상이 되는 것은 불필요한 일이다. /.gitignore 파일을 아래와 같이 작성하여 필요한 파일만 관리되도록 설정한다.

.gradle
/build/
/out/
!gradle/wrapper/gradle-wrapper.jar

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
.nb-gradle/

Application.java 작성

@SpringBootApplication 어노테이션이 붙는 클래스는 Spring Boot 프로젝트 실행의 시작점이다. /src/main/java/com.jsonobject.example/Application.java 파일을 아래와 같이 작성한다.

package com.jsonobject.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class, args);
    }
}
  • Spring Boot 기반의 웹 애플리케이션은 ApplicationContext 오브젝트를 어디에 저장될까? 바로 ServletContext의 애트리뷰트(Key: org.springframework.web.context.WebApplicationContext.ROOT, Value: AnnotationConfigEmbeddedWebApplicationContext 오브젝트)에 저장한다. 따라서 ServeltContext와 같은 생명주기를 가질 수 있다.

HelloController.java 작성

Spring Boot 프로젝트 개발을 위한 최소한의 준비가 끝났다. @Controller 클래스를 작성해보자. /src/main/java/com.jsonobject.example/HelloController.java 파일을 아래와 같이 작성한다.

package com.jsonobject.example;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @RequestMapping("/")
    public String hello() {

        return "Hello, Spring Boot!";
    }
}

실행 및 디버그

  • Spring Boot 기반 프로젝트의 장점은 복잡한 실행 과정이 필요 없는 바닐라 자바 애플리케이션이라는 것이다. 교과서에서 배운 대로 main() 메써드를 실행하거나 디버그하면 된다. 본 예제에서는 Application.java로 이동하여 우클릭 후 Run 'Application.main()'(디버그는 Debug 'Application.main()')을 실행하면 된다.

테스트

  • 앞서 실행 및 디버그를 실행했다면 기본 포트인 8080를 리스닝한 상태로 애플리케이션이 작동하게 된다. Postman을 실행하여 http://localhost:8080/ 요청이 작동하는지 확인해보자. 화면에 Hello, Spring Boot! 문자열이 출력되었다면 정상적으로 실행된 것이다.

빌드

Spring Boot로 제작한 애플리케이션을 빌드하면 1개의 .jar 파일이 생성된다.

  • Shift 키 2번 연타 -> Gradle 입력 후 Tool Windows: Gradle 선택 -> Tasks -> build -> build 실행
  • /{project_location}/build/libs/{project_name}-{version}.jar 경로에서 빌드되어 생성된 .jar 파일을 확인할 수 있다.
  • 별도로 Gradle을 설치했다면 프로젝트 루트에서 아래와 같이 실행해도 결과는 같다.
# 프로젝트 빌드, /build/libs/{jar.baseName}-{jar.version}.jar 파일 생성
$ gradle build

운영 환경 적용

  • 운영 환경에선 빌드된 .jar 파일은 아래와 같이 서비스로 등록하여 실행할 수 있다.
# 운영 환경에서는 서비스로 등록하여 실행 제어
$ sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp

$ chmod 0755 /etc/init.d/myapp

# 애플리케이션 시작 옵션 설정 (.jar 파일과 동일한 디렉토리에 위치해야 하며 파일명은 .jar와 동일하게 설정)
$ nano /var/myapp/myapp.conf
PID_FOLDER='/home/apps'
LOG_FOLDER='/var/log/myapp'
JAVA_OPTS='-Xms8g -Xmx8g -XX:MaxMetaspaceSize=512m -server -Dspring.profiles.active=prod'

# 애플리케이션 시작
$ service myapp start

# 애플리케이션 종료
$ service myapp stop

# 애플리케이션 재시작
$ service myapp restart

# 애플리케이션 상태 확인
$ service myapp status
  • service {app} stop 명령은 kill {app_pid} 명령과 동일하다. 실행 중인 JVM에 종료 시그널을 전달하여 사용 중인 자원을 반환하고, 실행 중인 쓰레드를 모두 안전하게 종료한 후에 애플리케이션을 최종적으로 종료한다.(Graceful Shutdown) 반면에 kill -9 {app_pid} 명령은 애플리케이션을 강제로 종료하므로 사용에 있어 주의해야 한다. [관련 링크]

  • 운영 환경에서는 Supervisor를 이용하여 애플리케이션 실행 주기를 정밀하게 제어할 수 있다. 이 방법을 추천한다. [관련 링크1] [관련 링크2]

결론

앞으로 Spring Boot 기반의 프로덕션 서비스를 구축하면서 경험하고 깨달은 것을 차근차근 글로 작성해보고자 한다. 작은 첫 시작으로 기본적인 프로젝트 생성 글을 작성하였고 앞으로 계속 새로운 글을 작성할 예정이다.

참고 글

다음 단계로 읽을만한 글

저작자 표시 비영리 동일 조건 변경 허락
신고