Bean for Properties

Annotation Processor (spring-boot-configuration-processor) 추가하기

우선, build.gradle 의 buildscript에 다음과 같이 추가한다. 이 때, 0.0.9 로 명시된 버전은 여기(https://github.com/spring-gradle-plugins/propdeps-plugin/tags\ 에서 확인 후, 가장 최신 버전으로 적어준다.

buildscript {
    repositories {
        //...
        maven { url 'http://repo.spring.io/plugins-release' }
    }
    dependencies {
        //...
        classpath 'io.spring.gradle:propdeps-plugin:0.0.9.RELEASE'
    }
}

또, buildscript 와 형제 관계로 다음을 설정한다.

//..생략
configure(allprojects) {
    apply plugin: 'propdeps'
    apply plugin: 'propdeps-maven'
    apply plugin: 'propdeps-idea'
    apply plugin: 'propdeps-eclipse'
}

그 후, gradle install 을 실행한다. 추가적으로, eclipse 를 쓰는 개발자들을 위해 gradle eclipse를 실행하거나, intellij 를 위해 gradle idea를 실행할 수도 있다. ((당연히) 프로젝트의 루트 디렉토리에서 커맨드를 실행한다.)

이로서 gradle 에서 추가적으로 optional, provided 등을 쓸 수 있게 해주는 propdeps-plugin (https://github.com/spring-gradle-plugins/propdeps-plugin\ 설치가 완료되었다.

이 후, 프로젝트에서 property를 다루기 위한 Annotation Processor인 spring-boot-configuration-processor 의존성을 지정하기 위해 build.gradle 에 다음을 추가한다.

dependencies {
    //..
    optional "org.springframework.boot:spring-boot-configuration-processor"
}

compileJava.dependsOn(processResources)
출처
https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/html/configuration-metadata.html#configuration-metadata-annotation-processor

@ConfigurationProperties 다루기

customized Configuration Property 들을 쓰고 싶다면 같은 종류의 customized Configuration Property 들을 하나의 vo bean 에 담아서 사용하는 것이 효과적이다. 해당 bean 은 아래처럼 Configuration Property 를 필드로 갖고 있고 setter 와 getter 가 선언되어 있다.

package com.example.demo.property;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties("amazon")
public class AmazonProperties {

    private String associationId;
}

이렇게 한 후, amazon.associationId 가 application.yml 또는 환경변수 등에 property 로 선언되어 있으면 된다. 프로파일이 적용됨은 물론이다. 예시는 다음과 같다.

amazon:
  associationId: jjangga@
Tip. Configuration Property naming

java 에서 Configuration property는 camel case naming 을 따른다. 그러나, .yml 이나 .properties 파일에 설정할 때에는 꼭 camel case 가 아니어도 된다. 예를 들어 아래 3가지 표현은 모두 같은 표현이다. (Id 인지 id 인지 i 의 대소문자 여부는 naming convention 에 따라 다르다.)

  • amazon.associationId
  • amazon.association_id
  • amazon.association-id

Nested Configuration Properties

중첩된 Configuration Properties 들은 다음과 같이 처리한다. (다른 방식(Map 사용 등)으로 처리하기 위한 것은 아래의 2번째 출처(baeldung)를 확인한다. )

package io.mama.index.vo.property;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * mama.env.http-port=8080 과 같이 설정된 Configuration Property 에 접근한다.
 */
@Data
@ConfigurationProperties(prefix = "mama")
@Component
public class MamaProperties {

    private Env env;

    @Data
    public static class Env { // public 이어야 한다.!
        private int httpPort;
    }
}
출처
https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/html/configuration-metadata.html#configuration-metadata-annotation-processor

# 여러가지 다양한 방식 
http://www.baeldung.com/configuration-properties-in-spring-boot

Usage

아래와 같이 위에서 선언한 bean 을 실제 사용할 곳에 DI 하여 property 의 값을 사용하면 된다.

// 생략

@RequestMapping("/")
@Controller
public class ReadingListController {

    private ReadingListRepository readingListRepository;
    private AmazonProperties amazonProperties;

    @Autowired
    public ReadingListController(ReadingListRepository readingListRepository, AmazonProperties amazonProperties) {
        this.readingListRepository = readingListRepository;
        this.amazonProperties = amazonProperties;
    }

    @RequestMapping(method = RequestMethod.GET)
    public String readersBooks(Reader reader, Model model) {

        List<Book> bookList = readingListRepository.findByReader(reader);
        if (Objects.nonNull(bookList)) {
            model.addAttribute("books", bookList);
            model.addAttribute("reader", reader);
            model.addAttribute("amazonAssociationId", this.amazonProperties.getAssociationId());
        }

        return "readingList";
    }

// 생략

results matching ""

    No results matching ""