@ConfigurationProperties 어노테이션과 @ConstructorBinding을 이용한 Database Configuration 설정.

안녕하세요. 오늘은 @ConfigurationProperties 어노테이션을 활용하여 스프링의 db 설정을 관리하는 방법을 소개해보겠습니다.

 

https://sas-study.tistory.com/327

 

[Spring Boot] 스프링부트 @ConfigurationProperties 어노테이션으로 application.properties에서 관리하기

@ConfigurationProperties @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ConfigurationProperties { @AliasFor("prefix") String value(..

sas-study.tistory.com

같은 내용을 이전에 포스팅한적이 있는데 여기서 한단계 발전한 관리방법이라고 보시면 되겠습니다.

 

해당 실습에 사용된 코드는 여기에서 확인하실 수 있습니다.

 


사전 준비

필요 의존성

- Postgresql(다른 디비도 됩니다. driver class name 만 알고있으면 됩니다.)

- lombok

- 스프링부트 버전 2.2 이상

- 예제에서 진행된 pom 문서는 아래와 같습니다.

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>sas.study</groupId>
    <artifactId>blog</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>blog</name>
    <description>코딩하는흑구 티스토리 블로그용 레포지토리</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

 

1. application.properties 혹은 application.yml 에 datasource 설정하기.

spring.datasource.url=jdbc:postgresql://localhost:5432/blog
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.username=디비유저
spring.datasource.password=디비비번

기존에 스프링부트를 활용했다면 다음과 같이 설정해놓으시면 스프링 부트의 AutoConfiguration에 의해서 해당 properties들이 읽혀서 데이터베이스 설정이 자동으로 진행되었을 것입니다.

 

이번 포스팅의 목적은 해당 설정을 읽어서 데이터 바인딩을 진행해보는 것입니다. 고로 여기까지 작성한다면 스프링부트가 잘 실행될것입니다.

 

2. Properties 클래스 생성

@Getter
@Validated
@AllArgsConstructor
@ConstructorBinding
@ConfigurationProperties(prefix = "spring.datasource")
public class PostgresProperties {

    @NotEmpty
    private final String url;

    @NotEmpty
    private final String driverClassName;

    @NotEmpty
    private final String username;

    @NotEmpty
    private final String password;

}

이전 포스팅에도 진행했듯이! @ConfigurationProperties 어노테이션을 활용하여 spring.datasource라는 prefix를 설정하였고 해당 prefix를 활용해 url, driverClassName(규칙에 의해 이렇게 써도 바인딩이됨), username, password를 바인딩하게 됩니다.

 

@ConstructorBinding 어노테이션은 @ConfigurationProperties 어노테이션의 주석내용을 보면

Annotation for externalized configuration. Add this to a class definition or a @Bean method in a @Configuration class if you want to bind and validate some external Properties (e.g. from a .properties file).
Binding is either performed by calling setters on the annotated class or, if @ConstructorBinding is in use, by binding to the constructor parameters.

ConstructorBinding이 사용중이라면 생성자 파라미터 바인딩을 한다고 하네요. 실제로 PostgresProperties 클래스를 컴파일 했을 때는 아래와 같이 클래스파일이 생성되는 것을 볼 수 있습니다.

 

- 컴파일된 PostgresProperties

@Validated
@ConstructorBinding
@ConfigurationProperties(
    prefix = "spring.datasource"
)
public class PostgresProperties {
    @NotEmpty
    private final String url;
    @NotEmpty
    private final String driverClassName;
    @NotEmpty
    private final String username;
    @NotEmpty
    private final String password;

    public String getUrl() {
        return this.url;
    }

    public String getDriverClassName() {
        return this.driverClassName;
    }

    public String getUsername() {
        return this.username;
    }

    public String getPassword() {
        return this.password;
    }

    public PostgresProperties(final String url, 
                              final String driverClassName, 
                              final String username, 
                              final String password) {
        this.url = url;
        this.driverClassName = driverClassName;
        this.username = username;
        this.password = password;
    }
}

맨 아래에 있는 생성자로 바인딩이 된다는 이야기입니다. 실제로 바인딩이 잘 진행되었는지 테스트코드를 통해 확인해보겠습니다.

 

@EnableConfigurationProperties({PostgresProperties.class})
@SpringBootApplication
public class BlogApplication {

    public static void main(String[] args) {
        SpringApplication.run(BlogApplication.class, args);
    }

}

@EnableConfigurationProperties 어노테이션의 인자로 PostgresProperties 클래스 타입을 넣어줍니다. 

Enable support for @ConfigurationProperties annotated beans. @ConfigurationProperties beans can be registered in the standard way (for example using @Bean methods) or, for convenience, can be specified directly on this annotation.

 

3. Binding 확인 테스트 코드 작성

@SpringBootTest
class BlogApplicationTests {

    @Autowired
    PostgresProperties postgresProperties;

    @Test
    void contextLoads() {
        assertThat(postgresProperties).extracting("url").isEqualTo("jdbc:postgresql://localhost:5432/blog");
        assertThat(postgresProperties).extracting("driverClassName").isEqualTo("org.postgresql.Driver");
        assertThat(postgresProperties).extracting("username").isEqualTo(디비유저);
        assertThat(postgresProperties).extracting("password").isEqualTo(디비비번);
    }

}

PostgresProperties의 바인딩을 확인하기 위해서는 스프링이 올라가야합니다. 따라서 @SpringBootTest로 진행해야 합니다. 

위의 "디비유저"와 "디비비번" 은 각 사용자마다 다르기때문에 본인의 Local Database의 유저를 적어주어야 합니다.

이 부분은 잘 보시고 진행해주세요.

 

테스트를 실행하니 잘 동작하는 것을 확인할 수 있습니다.

 

댓글

Designed by JB FACTORY