본문 바로가기

IT공부/스프링부트

스프링부트 1강 - 스프링부트 소개

스프링부트 1강 - 스프링부트 소개

목차

  1. 스프링 부트 소개
  2. 스프링 부트 프로젝트 만들기
  3. 스프링 부트 웹 서비스 개발

스프링 부트 소개

스프링 부트가 나온 것은 2014년 4월 1일이다. 스프링부트는 기존에 스프링 프레임워크와 같이 톰캣과 같은 WAS가 설치된 곳에 WAR를 배포하는 게 아니라 자기 자신 자체를 배포하고 실행할 수 있는 그런 아키텍처를 가진다. 스프링부트 2.0은 2018년 3월 1일에 나왔다. 

스프링부트 기능정의

  • 단독실행 가능한 스프링 애플리케이션 생성
  • 내장 컨테이너로 톰캣, 제티 혹은 언더토우 중에서 선택가능
  • 스타터를 통해 간결한 의존성 구성 지원
  • 스프링에 대한 자동구성(Auto-Configuration) 제공
  • 더이상 XML구성 필요없음
  • 제품출시 후 운영에 필요한 다양한 기능(상태점검, 모니터링 등) 제공

스프링부트는 스프링 프레임워크를 기반으로 한 개발플랫폼이다. 아두이노라고 하는 작은 개발툴킷처럼 필요한 모듈을 꽂아서 동작시키는 것처럼 스프링부트라고 하는 개발플랫폼 위에 스타터라고하는 제공되는 라이브러리 기능들을 하나씩 얹으면서 애플리케이션의 기능을 확장하는 그런 플랫폼적인 특성을 가진다. 

스프링 부트 구성요소

요즘은 그레이들을 많이 쓴다. 스프링부트는 스프링 프레임워크 기반으로 동작한다고 했는데 스프링부트 1점대와 2점대가 있다. 스프링 부트를 1점대를 사용할 건지 2점대를 사용할 건지에 대한 고민도 필요하다. 스프링 부트 스타터는 스프링부트의 의존성관리를 한다. 위 4가지 구성요소가 합쳐져 스프링부트라고하는 개발플랫폼을 이룬다. 

프로젝트를 빌드하고 배포하는 과정에서 수많은 코드를 구현한다. BCD라는 과정을 통해서 스프링부트를 설명한다. 

https://start.spring.io/에 접속하면 스프링부트를 시작할 수 있는 UI를 제공한다. STS나 인텔리제이라고 하는 개발도구도 이 사이트에 요청을 날려서 프로젝트를 생성하고 그 파일을 내려받고 불러오기해서 쓰는 방식을 이용한다. 사이트에 접속하여 아래와 같이 설정을 한 뒤 generate 버튼을 누르자. 자바 프로젝트에는 패키지 명을 가지고 기본적인 프로젝트 구성을 하게되는데 GROUP에는 패키지명을 적으면 된다. 스프링 부트는 톰캣을 기본 컨테이너로 한다. 하지만 다른 컨테이너로 변경할 수 있다. 

spring-boot.zip이라고 하는 파일을 다운로드받는다. 

 F12를 눌러 개발자도구를 열고 링크를 카피하자.

카피하면 아래와 같은 URL을 확인할 수 있다.

https://start.spring.io/starter.zip?type=gradle-project&language=java&bootVersion=2.3.0.RELEASE&baseDir=spring-boot&groupId=io.honeymon.tacademy&artifactId=spring-boot&name=spring-boot&description=Demo%20project%20for%20Spring%20Boot&packageName=io.honeymon.tacademy.spring-boot&packaging=jar&javaVersion=1.8&dependencies=web,lombok,data-jpa,h2

GENERATE 버튼을 클릭하면 위 URL을 호출하고 spring-boot.zip이라고 하는 파일이 다운로드되는 것이다. 

스프링부트가 지원하는 언어는 Java, Kotlin, Groovy이다. 

그레이들과 메이븐은 프로젝트의 의존성과 빌드동작을 선언하는 스크립트가 있다. 

 

그레이들(Gradle) - build.gradle

buildscript { //그레이들 바이너리 플러그인 버전 정의

         ext {

                 springBootVersion = '2.0.4.RELEASE'  // 스프링 부트 버전 정의

         }

         repositories {

                   mavenCentral()

                   maven { url "https://plugins.gradle.org/m2" } // 그레이들 플러그인 저장소

         }

         dependencies { //바이너리 플러그인 의존성 정의

                   classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")

         }

}

 

apply plugin : 'java' //언어 플러그인

apply plugin : 'eclipse' // eclipse 지원기능 제공

apply plugin : 'idea'    // intelij 지원기능 제공(sourceSets)

apply plugin : 'org.springframework.boot' //스프링 부트 그레이들 플러그인 정의

 

group =  "io.honeymon.boot"

version = "1.0.0.RELEASE"

 

jar { // jar 패키징시 파일명 및 버전기준 선정

       baseName = "${project.name}"

       version = "${project.version}"

}

 

그레이들은 build.gradle 이라고 하는 스크립트가 있다. 스프링부트는 제일 상단에 buildscript라고 하는 선언부에서 스프링부트 플러그인을 필요로하게 된다. 메이븐에서도 스프링부트 플러그인이라고 하는 플러그인이 필요하다. 하단에 보면 위에서 입력했던 GROUP정보와 버전정보가 보인다. 그리고 밑에 jar는 java라고 하는 언어 플러그인이 활성화되었을 때 패키징하는 파일과 그 안에 있는 정보를 지정하는 것이다. 

 

메이븐(Maven) - pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

     <modelVersion>4.0.0</modelVersion>

 

     <groupId>io.honeymon.springboot.boot</groupId>

     <artifactId>boot-spring-boot</artifactId>

     <packaging>jar</packaging>

 

     <name>boot-spring-boot</name>

     <description>Boot Spring Boot Project</description>

     <url>https://github.com/ihoneymon/boot-spring-boot</url>

     <organization>

             <name>honeymon.io</name>

             <url>http://honeymon.io</url>

     <organiztion>

     

     <parent> <!-- spring-boot-parent 정의 및 스프링 부트 버전 정의 -->

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-starter-parent</artifactId>

                <version>2.0.3.RELEASE</version>

                <relativePath/>  <!-- lookup parent from repository -->

    </parent>

    

   <!-- 생략 -->

 

메이븐의 빌드 스크립트이다. pom.xml이라고 하는 이름을 가진다. IDE에서는 기본적으로 그레이들과 메이븐에 대한 의존성이나 작성편의를 제공하고 있기 때문에 위 스크립트를 하나하나 작성할 필요는 없다. 

프로젝트 기본 코드구조

생성된 프로젝트 기본 코드구조는 위와 같은 구조이다. 위 구조는 그레이들을 기반으로 한 코드구조이다. 1번은 앞에서 봤던 build.gradle 파일이고 2번은 최근에 wrapper라고 해서 수동으로 로컬에 설치할 필요없이 프로젝트에 내장을 시켜서 빌드를 하는 쪽으로 권장을 하고 있다. 3번 gradlew는 리눅스나 유닉스계열에서 실행되는 스크립트이다. 4번은 윈도우 쪽에서 실행되는 배치파일이고 5번은 프로젝트의 기본적인 구성을 정의하는 부분이다. src 하위 구조는 메이븐에서 기본적으로 갖게되는 코드구조이고 빌드가 실행되면 실제 컴파일 단계에서는 src/main/java와 src/main/resources 부분만 컴파일되서 패키징이 되어 배포가 된다.  

스프링부트에서 빌드를 하게 되면 실행가능한 JAR, WAR라는 용어가 많이 나온다.

실행가능한이라는 단어가 왜 붙었느냐 생각해보면 기존에 고전적인 배포형태는 톰캣과 같은 WAS가 설치되어 있고 그 WAS의 특정 위치에 springboot.war라고 하는 배포본을 업로드를 하면 톰캣이 그 파일을 읽어들여서 실행을 하는 형태였다면 지금의 배포형태는 우리가 만든 springboot.jar 파일과 임베디드 컨테이너(내장형 컨테이너) 톰캣을 한 데 묶어서 다시 한번 패키징하는 부트리패키징이 발생하게 된다. 그래서 이 JAR파일을 가지고서 java, jar springboot.jar라고 하면 바로 실행가능한 형태가 된다. 도커나 쿠버네티스 컨테이너 안에서도 실행가능한 JAR를 배포하고 그 안에 JAVA 빌드팩을 설치해서 작은 단위의 컨테이너 안에서 애플리케이션을 실행할 수 있도록 지원을 하고 있다. 

스프링 부트 1.5.X 와 2.X 가 있다. 2개의 큰 차이는 스프링 프레임워크 4.3을 쓰느냐 5점대를 쓰느냐이다. 가능하면 스프링 부트 2.0부터 사용하기를 권장한다. 2019년 8월 1일이 되면 생을 마감시키겠다고 필 웹이 이야기했다. 내년도까지는 1.5되서도 업그레이드가 나오고 취약한 부분을 핫픽스하면서 나오긴 하겠지만 어쨋든 주가 되는 것은 스프링부트2.0을 중심으로 한다는 것이다. 

나중에 스프링부트 어플리케이션 코드를 보겠지만 그 안에 보면 위와 같은 어노테이션들이 있다. @SpringBootApplication 어노테이션이 있고 @ComponentScan 이 어플리케이션이 컴포넌트스캔을 어떤 범위로 할 건지 지정하는 것이고 @EnableAutoConfiguration 어노테이션은 자동구성을 활성화하겠다는 선언이고 @Configuration은 구성 빈을 쓰겠다라는 의미이고 @ConditionalOn 접두사를 가지고 있는 어노테이션들은 이런이런 조건이 되었을때 활성화를 하겠다는 의미이고 @SpringBootConfiguration 어노테이션은 @Configuration 어노테이션과 같은 동작을 하는데 스프링과 스프링부트를 구분짓기 위해서 만들었다. @EnableConfiguraionProperties 어노테이션은 스프링부트의 어플리케이션 속성을 정의할 수 있는데 이거를 클래스에 릴렉스드 바인드라고 해서 유연하게 연동할 수 있는 기능을 키겠다는 의미이다. @ConfigurationProperties 어노테이션은 애플리케이션의 속성들을 클래스에 연동하는 동작들을 지정한다. 

/**

 * 스프링 부트 애플리케이션이 시작되는 곳!

 * {@link SpringBootApplication}을 살펴보세요. 스프링 붙의

 * 마법이 시작되는 곳입니다.

 *

 * @author honeymon

 */

//@SpringBootApplication어노테이션을 빼면 그냥 자바 어플리케이션이다. 

@SpringBootApplication

public class BootSpringBootApplication {

   //main메서드라는 엔트리 포인트 (진입점) 기준으로 해서 어플리케이션이 실행이 된다. 

   public static void main(String[] args) {

           //SpringApplication이라는 클래스가 있다. run 메서드로 실행을 하면 스프링 IOC 컨테이너를 실행시키고 @Sp

           //ringBootApplication 어노테이션이 붙은 위치를 기준으로 하향식으로 밑에 있는 패키지를 쭉 탐색을 하는게 

           //스프링 부트의 기본적인 동작방식이다. 

           SpringApplication.run(BootSpringBootApplication.class, args);

   }

}

의존성을 간결하게 할 수 있는 스프링 부트 스타터가 있다. 

스프링 부트 스타터는 spring-boot-autoconfigure와 spring-boot-dependencies라는 2개의 모듈이 합쳐져서 기본동작을 한다. 2개의 모듈이 합쳐진 스프링 부트 스타터를 기준으로 해서 스프링 부트 스타터 웹, 스프링 부트 스타터 시큐리티, 스프링 부트 스타터 JPA 등 기능별로 모듈을 정의하고 의존성등을 설명하고 있다. 

스타터를 통해 간결한 의존성 구성 지원

dependencies {

   complie("javax.annotation:javax.annotation-api:${annotationApiVer}")

   complie("org.springframework:spring-core")

   complie("org.springframework:spring-web:${SpringFrameWorkVer}")

   complie("org.springframework:spring-webmvc:${SpringFrameWorkVer}")

   complie("org.hibernate.validator:hibernate-validator${hibernateValidatorVer}")

 

   //jackson

   complie("com.fasterxml.jackson.core:jackson-databind:${jacksonVer}")

   complie("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${jacksonVer}")

   complie("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${jacksonVer}")

   complie("com.fasterxml.jackson.module:jackson-module-parameter-names:${jacksonVer}")

 

   complie("org.yaml:snakeyaml")

 

   //logging

   compile("ch.qos.logback:logback-classic:${logbackVer}")

   compile("org.apache.logging.log4j:log4j-to-slf4j:${log4jVer}")

   compile("org.slf4j:jul-to-slf4j:${slf4jVer}")

}

 

스프링 부트 스타터를 이용하며 위 코드가 아래와 같이 바뀐다.

 

dependencies {

   compile("org.springframework.boot:spring-boot-starter-web")

}

 

spring-boot-starter-web이라고 하는 스타터하나를 통해서 위에 보이는 긴 의존성들을 한 번에 사용할 수 있는 것이다. 스프링 부트 스타터를 사용하지 않으면 각 라이브러리마다 버전을 명시해야 하는 불편함이 있다. 

 

개발자가 신경서야 하는 것

  • 스프링 부트 버전!
  • 사용하려는 라이브러리의 스프링 부트 스타터 지원여부!
  • 지원하지 않는 경우 사용하려는 라이브러리 등록방법!

스프링부트는 피보탈이라고하는 개발업체에서 주도적으로 관리하고 있는 오픈소스이다. 오픈소스이기때문에 스프링부트가 동작하는 모든 코드를 깃헙에 가면 다 볼 수 있다.(https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-starters)

이 곳에 가면 스프링부트가 제공하는 스타터 목록들을 볼 수 있다. spring-boot-starter 접두사가 붙은 것은 스프링부트에서 공식적으로 지원하는 모듈들이다. 커뮤니티에서 스타터를 제공하는 경우도 있다. 마이바티스 모듈을 제공하는 스타터를 마이바티스에서 제공을 한다. 이 모듈을 추가하면 스프링 부트에서 마이바티스를 사용할 수도 있다.

스프링 부트는 이 스타터들이 추가가 되면 자동구성되어 있는 구성이 활성화되면서 관례적인 빈 구성을 하게된다. 

Auto-Configuration

  • http://bit.ly/2MCnqHV -> spring-projects/spring-boot/spring-boot-autoconfigure(모듈) 기본적으로 스프링부트에서 제공하는 자동구성은 스프링부트 위 경로에 들어가 있다. 
  • 스프링 부트가 기술흐름에 따라 제공하는 관례(Convention)적인 구성
  • 봐야할 모듈: spring-boot-autoconfigure
  • 동작선언                                                                                                    
    • @EnableAutoConfiguration(in @SpringBootApplication)
    • @Configuration
  • 사용 애너테이션(자동구성에서 사용하는 애너테이션)
    • @Configuration
    • @ConditionalOn
      • 있거나 없거나(미싱빈, 미싱클래스, true or false 조건에 따라서 활성화되는 구성)
  • ~AutoConfiguration 접미사

어플리케이션 속성을 외부에서 주입받아서 애플리케이션이 동작할 때 적용할 수 있다. 

외부구성 적용 우선순위

  1. 실행인자
  2. SPRING_APPLICATION_JSON
  3. 환경변수
  4. 기타등등
  5. application.yml or application.properties
  6. application-{defaultproflies}.yml or application-{defaultproflies}.properties

우선순위는 13가지 단계가 있는데 개발자가 신경쓸 부분들은 위와 같이 6개이다. 실행인자는 터미널에서 실행하거나 aws에서 환경변수로 전달하는 경우들이 해당되고 SPRING_APPLICATION_JSON은 서버 안에 JSON으로 선언한 구성파일의 위치를 지정하면 우선순위가 생기고 환경변수는 운영체제 환경변수를 의미한다. AWS에서 구성을 할 때 환경변수관련한 부분을 많이 쓴다. application-{defaultprofiles}.yml or application-{defaultproflies}.properties는 로컬, 개발, 운영등의 실행환경을 profiles로 구분을 짓는데 프로파일을 갖는 애플리케이션 속성 파일을 읽어드린다. 

스프링 부트는 스프링 프레임워크 기반으로 동작을 하기 때문에 조금 더 잘 사용하기 위해서는 스프링 프레임워크를 이해하는 과정이 필요하다. 

Programming in Spring Enviroment(스프링에서 어노테이션기반 작동방식)

  • @ComponentScan을 통해 ApplicationContext(등록된 빈이 ApplicationContext에 적재됨) 적재
    • @Repository
    • @Component
    • @Service
    • @Controller & @RestController
    • @Configuration
      • @Bean
      • @ConfigurationProperties
    • DI, IOC, @Autowired
    • @Value vs @ConfigurationProperties
    • AOP
    • ...등등

위에 나열된 스프링 프레임워크에 대한 기본적인 공부가 필요하다. 이걸 기반으로 해서 업무(비지니스 로직)을 구현하는 것이다.

 

스프링 프레임워크는 2004년 3월 24일에 출시되었다. 

스프링 프레임워크를 공부하고 싶다면 토비의 스프링, 스프링5 레시피, 스프링 5 프로그래밍 입문, 자바 ORM 표준 JPA 프로그래밍 책을 추천한다. 

 

배포는 그레이들을 통해서 만들어진 실행가능한 jar나 war 파일을 리눅스 서버에 배포해서 그 안에서 java jar 커맨드로 실행시킬 수도 있고 아니면 고전적인 배포방법으로 톰캣같은 WAS에 WAR를 배포해서 실행시킬 수도 있다. 아니면 AWS, AZURE, GCP같은 클라우드 플랫폼에 자바실행환경에다가 배포를 해서 실행하는 방법등 다양할 방법들이 있다. AWS 기반으로 한 배포운영방법에 대해서 설명을 할 것이다.