스프링 부트 원리 (2)

자동 설정 구현

  • 보통 configure와 starter는 패키지를 나누어서 만듦
    • xxx-spring-boot-autoconfigure 모듈: 자동 설정
    • xxx-spring-boot-starter 모듈: 필요 의존성 정의
  • 그러나, 그냥 하나로 만들고자 할 때는 xxx-spring-boot-starter에 함께 집어 넣음
  • 구현 방법
  1. 의존성 추가
<dependencies>
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-autoconfigure</artifactId>
  </dependency>
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-autoconfigure-processor</artifactId>
      <optional>true</optional>
  </dependency>
</dependencies>
     
<dependencyManagement>
  <dependencies>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-dependencies</artifactId>
          <version>2.0.3.RELEASE</version>
          <type>pom</type>
          <scope>import</scope>
      </dependency>
  </dependencies>
</dependencyManagement>
  1. @Configuration 파일 작성
  2. src/main/resource/META-INF 폴더에 spring.factories 파일 만들기
  3. spring.factories 안에 자동 설정 파일 추가
    #groupID + Configuration 파일명
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.devfon.HolomanConfiguration
  1. mvn install
  • 다른 maven project에서도 사용이 가능해지도록 local maven 저장소에 jar 파일 설치하게 됨
  • 다른 프로젝트에서는 아래와 같이 다른 프로젝트에서 의존성 추가하여 사용
<dependency>
    <groupId>com.devfon</groupId>
    <artifactId>devfon-spring-boot-starter</artifactId>
    <version>1.0-SNAP</version>
</dependency>
  • 아래와 같이 의존성이 추가된 것을 확인할 수 있음

  • but, 한 가지 문제가 발생!
    • Component Scan으로 새로운 Bean을 등록한다 하더라도, 이후에 AutoConfiguration의 Bean을 다시 등록하기 때문에 AutoConfiguration의 Bean이 이전 Bean을 무조건 덮어쓰는 문제
    • 이를 해결하기 위해서는 @ComponentScan으로 읽힌 Bean들이 항상 우선 시 되어야 함
    • 해결 방법: @ConditionalOnMissingBean
      • AutoConfiguration에서 설정한 Bean에 @ConditionalOnMissingBean 애노테이션을 달아줌
  • 위 해결 방안을 통해 기정의된 convention이 아닌 내가 정의한 Bean의 사용이 가능해짐! -> "Customizing"
  • 더 나아가...
    • 다른 프로젝트에서 해당 Bean을 사용할 때, 매 번 Bean을 등록해주기가 번거롭다.
    • 다른 편리한 방법이 없을까?
    • ConfigurationProperties의 사용!
  1. jar 파일로 만들고자 하는 프로젝트에 ConfigurationProperties 파일 추가
@ConfigurationProperties("holoman")
public class HolomanProperties {

    private String name;
    private int howLong;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getHowLong() {
        return howLong;
    }

    public void setHowLong(int howLong) {
        this.howLong = howLong;
    }
}
  1. Configuration 파일에 EnableConfigurationProperties 옵션 추가
@Configuration
@EnableConfigurationProperties(HolomanProperties.class)
public class HolomanConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public Holoman holoman(HolomanProperties properties){
        Holoman holoman = new Holoman();
        // properties 파일로부터 값을 읽어와 생성하는 방식!
        holoman.setHowLong(properties.getHowLong());
        holoman.setName(properties.getName());

        return holoman;
    }
}
  1. jar 파일 사용하는 프로젝트의 application.properties에서 설정값 적용
holoman.name = sang
holoman.howLong = 365


[도서 리뷰] 스프링 부트 입문자를 위한 <처음 배우는 스프링 부트 2>



한빛미디어의 서평 이벤트로 <처음 배우는 스프링 부트 2> 책을 받아 읽어 보았다. 정말 초심자의 입장인 나의 상태로 책을 읽어 보았기에, 알맞은 눈높이에서 리뷰를 진행할 수 있을 것 같다는 생각으로 리뷰를 남겨본다.

1장

스프링 부트에 대한 기본적 소개와 간단한 특징들을 다루고 있다. 스프링 부트가 스프링에 비해 간결한 설정 방법을 가질 수 있는 이유는 무엇인지, 책을 관통하는 프로젝트 '커뮤니티 게시판'의 설계를 위해서는 어떠한 설계도가 필요한지에 대한 이야기가 주를 이룬다. 이후, starter가 포함하고 있는 의존 관계에 대한 짧은 설명이 등장하는데 사실 이 부분은 스프링 부트 혹은 스프링을 전혀 접해보지 못했다면 이해할 수 없는 부분이었던 것 같다. 하지만, 책을 두 번 째 보면서 그 중요성을 다시 느낄 수 있는 부분이었다.

2장

스프링 부트 기반의 프로젝트를 생성하기 위해 필요한 환경 설정에 대한 내용을 다룬다. 즉, 이번 장에서는 JDK, IntelliJ 그리고 빌드 툴인 Gradle의 활용법 등이 상세 내용으로 등장한다. JDK와 IntelliJ의 경우 스프링 부트 교재를 본다는 가정 하에 이 책을 보는 모든 독자가 아는 부분일 것이기 때문에 이 부분들을 줄이고, Gradle의 특징이나 활용법에 대해 더 다루었으면 좋았을 것 같다. 아무래도 maven 기반의 프로젝트를 실습해와본 독자들이 많았을 것이고, 나 같은 경우도 gradle 기반의 프로젝트를 처음 따라 배워보았다. 따라서 막히는 부분에 있어 검색할 때 정보가 많이 나오지 않아 답답한 부분이 종종 있었다. gradle에 대한 설명이 조금 더 추가되어 있었더라면 이러한 가려운 부분을 조금이나마 해결해줄 수 있었을 것 같다! 이후 중요한 애노테이션 설정들에 대한 설명이 들어간 것들은 아주 만족스러웠다.

3장

3장은 스프링 부트 테스트를 다루고 있다. 테스트 스타터로 뭉쳐진 의존성을 통해 스프링 부트가 얼마나 쉽게 테스트의 수행이 가능할 수 있는지 실습을 통해 보여주고 있는 장이다. TDD는 개발을 함에 있어 매우 중요한 덕목(?)으로 여겨지기 때문에 책에 등장해야 할만한 적합한 주제이긴 하나, 갑작스러운 등장이 약간 당황스러웠던 장이었던 것 같다. 3, 4장의 위치가 바뀌고 4장에서 생성하는 모듈들에 대한 단위 테스트를 실습하는 것을 이후에 보여주었다면 더 나은 구성이었을 것 같다는 생각을 해본다.

4장

가장 도움을 많이 받았던 스프링 부트 웹에 대한 설명을 다루고 있는 4장이다. 기본적인 게시판의 구현을 실습하며, 어떠한 전체 구조를 지녀야 웹 페이지를 설계할 수 있는지에 대한 지식을 얻을 수 있었던 장이었다. 또한 게시판 구현에서 어려움을 많이 발생시키는 페이징 처리나, 서버 사이드 템플릿 '타임리프'에 대한 정보를 다루고 있었던 것도 아주 만족스러웠다. 아마 나 같은 초심자에게는 이번 4장과 6장이 책에서 얻을 수 있는 가장 좋은 정보를 담고 있는 장이라고 생각한다.

5장

스프링 시큐리티와 oAuth에 대한 내용을 담고 있는 5장이다. 이 장 역시 알짜배기 장이었던 것 같다. 스프링 시큐리티가 사실 초보가 처음 접하기엔 어려운 부분이라고 생각하는데 좋은 설명과 실습으로 개념을 잘 진행할 수 있도록 구성이 잘 짜여져 있었던 장이다. 그리고 요즘 핫한 기술인 oAuth를 다루고 있다는 점에서 좋은 점수를 주고 싶다. 각종 sns와 어떻게 연동을 할 수 있는지를 친절한 설명을 통해 도와주고 있다.

6장

4장과 함께 굉장히 마음에 들었던 6장이다. 6장은 REST API 서버를 다루고 있다. 최근 Rest API에 대한 관심이 굉장하다고 생각한다. 내가 최근에 접해서 그 인기를 늦게 체감한 것일 수도.. 각설하고, 이 장이 특히 좋았던 이유는 Rest API의 구성을 MVC 패턴으로도 한 번, 스프링 데이터 레스트로도 한 번 설계해보며 그 설명의 끈을 이어나간다는 점이다. 저자의 섬세함이 돋보인 장이라고 생각한다. 초기 설정을 위해 DB로 사용하고 있는 MySQL에 대한 설명이 조금 들어있었다면 좋았을 것 같기는 하지만, 이 정도는 독자가 삽질하며 배워봐도 좋은 부분이라고 생각한다. 실제로 나는 mysql connector 설정 때문에 삽질을 많이 했다.. MySQL이 8 버전 이후로 넘어가면서 많은 default 설정들이 바뀌었던 것 같다. 그럼에도 삽질을 통해 웹 서버와 API 서버를 연동했을 때, 이 장의 빛을 다시 느낄 수 있었다!

7장

마지막 장은 스프링 부트 데이터 배치를 다루고 있다. 사실 이 장은 리뷰를 하기 민망할 정도로 주의 깊게 보지 못했다. 아직 어렵다.. 이후에 다시 실습해보면 리뷰를 할 수 있을 것 같다! 다만 평이 좋은 것을 보니 좋은 내용을 다루고 있는 것 같다.


총평

리뷰 이벤트를 통해 증정 받은 도서이긴 하지만 주위에 누군가 스프링 부트를 배워보고 싶다고 하면 주저없이 추천을 해주고 싶은 책이다. 책이 짧은게 아쉬울 정도로 알짜배기 내용들을 잘 녹아내고 있는 책이라고 생각을 한다. 아마, 조금의 분량이 더 주어졌다면 분명 더 좋은 퀄리티의 책이 되었을 것 같다. 저자 분이 처음 집필한 책이라고 들었는데 아마 이후에 더 좋은 책의 저자가 되실 것 같다. 초심자의 시선으로 유익하게 볼 수 있었다 :)

<처음 배우는 스프링 부트 2>의 자세한 내용은 한빛미디에 홈페이지에서 확인하실 수 있습니다.


스프링 부트 원리 (1)

의존성 관리 이해

  • spring-boot-dependencies -> spring-boot-starter-parent -> 내 프로젝트의 pom 순으로 의존성 계층 구조가 성립
  • spring-boot-dependencies의 dependencyManagement에 각종 의존성들에 대한 version이 모두 명시되어 있음
  • 따라서 내 프로젝트의 pom에 spring-boot-dependencies에 정의되어 있는 의존성을 사용하게 될 경우, 직접 version을 명시해주지 않더라도 version 정보를 가져오게 됨
  • 즉, 각각의 starter에 이미 의존성들이 제공되고 있기 때문에 우리가 직접 관리해야 할 의존성의 수가 줄어들게 됨
    • 우리가 관리해야 하는 일이 줄어든다는 의미
    • version up을 하고자 할 때, third-party library의 어느 version과 호환되는지 모르는 문제도 해결 가능
    • 깔끔한 의존성 관리
  • pom에서 지원하지 않는 의존성을 추가하고자 할 때는 직접 version을 명시해주어 함!
  • 특정 library의 특정 version의 사용을 원하는 경우 명시해주어 사용 가능 -> 편리한 Customizing
  • 자기만의 의존 구조를 성립시키고 싶을 때는? (두 가지 방법)
    1. 직접 parent pom을 만들어 현재 프로젝트의 parent로 만들고, 그 parent로 spring-boot-starter-parent를 두는 것 (추천)
      • 즉, spring-boot-starter-parent -> 내 프로젝트의 parent -> 내 프로젝트의 구조를 만드는 것
    2. 현재 프로젝트의 parent를 만들고, 해당 parent에 섹션을 만들어 spring-boot-starter를 추가하여 사용 (비추천)
      • but, spring-boot-starter에는 dependency들만 가져오는 것이 아니라, 그 밖의 다른 설정들이 존재
        • ex) java 1.8, UTF-8, 각종 yml, plugin 설정 등
      • 이 설정들을 가져오지 못하는 불편함 존재

의존성 관리 응용

    1. 버전 관리 해주는 의존성 추가
    • spring-boot-starter-data-jpa
    1. 버전 관리 안해주는 의존성 추가
    • ModelMapper: version을 명시해주어야 함
<dependency>
    <groupId>org.modelmapper</groupId>
    <artifactId>modelmapper</artifactId>
    <version>2.3.1</version>
</dependency>
  • What is ModelMapper?
# Source model
class Order {
    Customer customer;
    Address billingAddress;
}

class Customer {
    Name name;
}

class Name {
    String firstName;
    String lastName;
}

class Address {
    String street;
    String city;
}

# Destination model
class OrderDTO {
    String customerFirstName;
    String customerLastName;
    String billingStreet;
    String billingCity;
}

# Domain to DTO를 자동으로 해주는 기능!
ModelMapper modelMapper = new ModelMapper();
OrderDTO orderDTO = modelMapper.map(order, OrderDTO.class)
    1. 기존 의존성 버전 변경하기
    • 내 프로젝트 pom의 에 직접 명시해주어 변경 가능!
    <properties>
        <spring.version>5.0.6.RELEASE</spring.version>
        <java.version>1.9</java.version>
    </properties>

자동 설정 이해

  • @Configuration?
    • Bean을 등록하는 java 설정 파일
  • SpringBootApplication의 핵심 annotation들!
    • @SpringBootConfiguration
    • @ComponentScan
    • @EnableAutoConfiguration
  • 스프링 부트는 Bean을 두 번 등록
    1. ComponentScan으로 한 번
    2. EnableAutoConfiguration으로 또 한 번
  • 1단계: @ComponentScan
    • @Component을 달고 있는 class들을 Scan해서 Bean으로 등록
    • @Configuration, @Repository, @Service, @Controller, @RestController 들도!
  • 2단계: @EnableAutoConfiguration
    • springframework.boot.autoconfigure.EnableAutoConfigure 내 META-INF의 spring.factories 파일 읽어옴
    • 그 아래의 @Configuration들 읽어옴
    • but, @ConditionalOn'XxxYyyZzz'
      • 즉, 조건에 따라 Bean으로 등록하기도 하고, 안하기도 함!

+ Recent posts