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";
}
// 생략