ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring boot - 설정 파일 관리 (@Profile, @ConfigurationProperties,@Value,@PropertySource)
    Web/환경설정 관련 2024. 5. 10. 19:22

     

    • 개발 프로젝트를 진행하는 방식에 따라 동일한 어플리케이션을 개발, 테스트, 스테이징, 상용 등 여러 환경에서 배포해야하는 경우가 있다.
    • 이때 배포 환경에 따라 소스코드는 거의 변경되지 않고, 설정 정보만 다르게 해야 배포 작업이 편할 것이다.
    • 따라서, 설정 정보를 외부화해서 관리 하는 방법 들에 대해서 알아보자 

     

    Property 관리의 여러 가지 방법 


    1. SpringApplication 클래스 활용

     

    • SpringApplication 클래스를 사용하여 설정 정보를 정의할 수 있다. 
    • 이 클래스에는 java.util.Properties 또는 Map<String,Object>를 인자로 받는다. 
    • setDefaultProperties에 위 Properties나 Map으로 설정한 내용을 넣으면 된다. 
    • 위 방식은 소스코드로 정의하는 방식이므로, 한 번 정의하면, 나중에 바뀌지 않는 경우에 적합하다.
    @SpringBootApplication
    public class ManyConfigApplication {
    
    	public static void main(String[] args) {
    	    Properties properties = new Properties();
    		properties.setProperty("spring.config.on-not-found", "ignore");
    		properties.setProperty("spring.mvc.static-path-pattern","/newstatic/**");
    
    		SpringApplication application = new SpringApplication(ManyConfigApplication.class);
    		application.setDefaultProperties(properties);
    		application.run(args);
    
    	}
    
    }
    • 그냥 key - value 형태로 properties를 작성하는 간단한 방법이다.

     

    2. @PropertySource 사용

     

    • PropertySource 애너테이션을 사용해서 사용할 프로퍼티 파일을 지정할 수 있다. 
    • 해당 값을 Environment 클래스를 통해 쉽게 값을 꺼낼 수 있다.
    • 혹은 @Value 애너테이션으로 값을 꺼내서 바로 주입할 수도 있다. 
    • PropertySource는 YAML 파일을 지정해서 사용할 수 없고, 사용하려면 몇가지 추가 작업이 필요하다.
    • PropertySouce는 여러개 사용할 수 있다. 
    
    import jakarta.annotation.PostConstruct;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.core.env.Environment;
    
    @Configuration
    @PropertySource("classpath:db.properties")
    @Slf4j
    public class DbConfig {
        @Value("${spring.datasource.username}")
        String userName;
        @Value("${spring.datasource.driver-class-name}")
        String driver;
    
        @Autowired
        private Environment env;
    
        @Override
        public String toString(){
            return env.getProperty("spring.datasource.username")+env.getProperty("spring.datasource.driver-class-name");
        }
        @PostConstruct
        public void mynameIs(){
            log.info(this.toString());
        }
    }

     

     

     

    3. properties와 YAML 배포시  위치 지정

     

    • 기본적으로 application.properties나 application.yml을 다음 경로에서 찾는다.
      • classpath root
      • classpath /config 패키지
      • 현재 디렉토리
      • 현재 디렉토리 /config 디렉터리
      • /config 디렉터리의 바로 하위 디렉터리  
    • 이때 spring.config.location 프로퍼티를 사용하면, 다른 위치에 설정 파일을 읽어올 수 있다.
    • scr/main/resources/data 디렉터리에 yml 파일을 두었다고 가정
    1. java -jar 배포파일명.jar --spring.config.location=data/bb.yml
    2. java -jar 배포파일명.jar --spring.config.location=optional:data/bb.yml
    • 기본 위치 말고 위에 설정한 위치에서도 properties 파일을 찾는다. (기본 + 추가 경로에 설정 파일이 없으면 예외 발생)
    • optional을 붙이면, 설정 파일이 없더라도 애플리케이션이 일단 실행된다. 

     

    4. 운영 체제 환경 변수 

    • 운영 체제 환경 변수로 지정한 값을 properties 파일이나, yml에서 읽을 수 있다.
    • 윈도우 set <VAR>=<value> , 리눅스 export <VAR>=<value> 등 환경변수를 지정 
    • ${}에 환경변수 이름을 넣으면, 환경 변수의 값을 읽어서 주입해준다
    • :를 넣어서 기본 값을 지정해 줄 수 도 있다. 
    app.timeout=${APP_TIMEOUT:3000}

     

    5. 우선 순위

    • 프로퍼티 지정의 우선 순위는 다음과 같다.
      1. 명령행 인자
      2. 운영체제 환경 변수 
      3. 설정 정보 파일 
      4. @PropertySource
      5. SpringApplication 

     

    6. @ConfigurationProperties 커스텀 프로퍼티 만들기 

    • spring의 프로퍼티는 빌트인과 커스텀으로 나눌 수 있다. 
    • 빌트인 프로퍼티를 Environment 인스턴스에 바인딩해서 주로 사용하는데, 몇 가지 단점이 있다.
      • 프로퍼티 값 타입 안정성이 보장되지 않아, 런타임 에러 발생 가능성이 있다.(ex url, 이메일 주소 유효성 검증)
      • 프로퍼티 값을 일정한 단위로 묶어서 읽을 수 없고 @Value나 Environment로 하나 하나 읽어야 한다.
    • 위 단점 타입 안정성을 보장하고, 유효성을 검증할 수 있는 방법은 다음과 같다. 
    app.sbip.ct.name=CourseTracker
    app.sbip.ct.ip=127.0.0.1
    app.sbip.ct.port=9090
    app.sbip.ct.security.enabled=true
    app.sbip.ct.security.token=asddf998hhyqthgtYYtggghg9908jjh7ttr
    app.sbip.ct.security.roles=USER,ADMIN

      

    • 이를 읽어올 클래스를 다음과 같이 만들 수 있다. 
    package com.example.manyConfig.config;
    
    import lombok.*;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import java.util.List;
    
    @ConfigurationProperties("app.sbip.ct")
    @RequiredArgsConstructor
    @Getter
    @ToString
    public class AppProperties {
        private final String name;
        private final String ip;
        private final int port;
        private final Security security;
    
    
        @ToString
        public static class Security{
            private final boolean enabled;
            private final String token;
            private final List<String> roles;
    
            public Security(boolean enabled, String token, List<String> roles) {
                this.enabled = enabled;
                this.token = token;
                this.roles = roles;
            }
        }
    
    }
    • 해당 프로퍼티를 읽어온 객체를 주입받아, 아래와 같이 사용할 수 있다. 
    package com.example.manyConfig;
    
    import com.example.manyConfig.config.AppProperties;
    import jakarta.annotation.PostConstruct;
    import lombok.AllArgsConstructor;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Service;
    
    @Service
    @AllArgsConstructor
    @Slf4j
    public class AppService {
        private final AppProperties appProperties;
    
        public AppProperties getAppProperties(){
            return appProperties;
        }
    
        @PostConstruct
        private void totoString(){
            log.info(appProperties.toString());
        }
    }
    • @SpringBootApplication이 있는 시작 부분에 @EnableConfigurationProperties를 추가해주면 사용할 수 있다. 
    @SpringBootApplication
    @EnableConfigurationProperties(AppProperties.class)
    public class ManyConfigApplication {
    ...//
    }

     

    *스프링 3.2.1부터 위와 같이 작성했을 때 작동하지 않을 수 있다.

    • 밑에 처럼 Build and run using과 Run tests using이 Gradle이어야 한다. 

     


     

     

    Profile 활용 


    • Profile을 설정하면, 다양한 환경에서 지정된 properties 혹은 yml파일을 개발 및 운영환경에 따라 쉽게 전환해서 사용할 수 있다. 
    • 먼저 application.properties파일을 기본으로 
      • application-[name].properties로 만들면된다. 
      • 여기서 name에는 다음이 사용될 수 있다.  이것 말고도 여러가지 원하는 이름을 사용해도 된다. 
        • local : 로컬 환경
        • dev : 테스트 환경 

     

    • profile환경은 application.properties나 위에 작성된 여러 프로퍼티 주입 방식을 사용해서 
    •  spring.profiles.active=profile명(local,dev2,dev1 ..등)을 주면 된다. 
    spring.profiles.active=dev1

     

     

    @Profile 애너테이션 

    • 프로필을 통해 런타임 환경을 설정할 수 있는 기능이다.
    • 테스트 환경 등에서 여러 테스트를 돌리고 난 다음 프로덕션 환경으로 전환 하는 것을 어렵지 않게 할 수 있다.
    @Configuration
    @Profile("dev1")
    @PropertySource("classpath:application.properties")
    @Slf4j
    public class DbConfig {
        @Value("${spring.datasource.username}")
        String userName;
        @Value("${spring.datasource.driver-class-name}")
        String driver;
    
        @Autowired
        private Environment env;
    
        @Override
        public String toString(){
            return Arrays.toString(env.getActiveProfiles())+" HI  "+env.getProperty("spring.datasource.username")+env.getProperty("spring.datasource.driver-class-name");
        }
        @PostConstruct
        public void mynameIs(){
            log.info(this.toString());
        }
    }

    • 설정 정보를 dev2로 변경하면, 빈이 생성되지 않는다. 
    • 이와 같이 테스트 환경에서만 사용할 Bean을 @Profile 애너테이션을 사용해서 등록하거나, 하지 않을 수 있다.

     

     

     

    https://engkimbs.tistory.com/entry/Spring-%EC%8A%A4%ED%94%84%EB%A7%81-Profile-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98%EC%9D%84-%ED%86%B5%ED%95%9C-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95Spring-Environment-Configuration-Profile

     

    [Spring] 스프링 @Profile 어노테이션을 통한 환경 설정(Spring Environment Configuration, @Profile)

    | 스프링 환경설정(Spring Environment Configuration) 스프링에서는 프로필(Profile)을 통해 런타임 환경을 설정할 수 있는 기능을 제공한다. 이 기능을 이용하여 테스트환경에서 여러 테스트를 돌리고 난

    engkimbs.tistory.com

    https://www.yes24.com/Product/Goods/122002340

     

    실전 스프링 부트 - 예스24

    인류에겐 이런 스프링 부트 가이드북이 필요했다방대한 스프링 부트 공식 문서 중 실무에서 잘 쓰이는 팁을 찾기란 어렵다. 이 책은 초급에서 중급 수준의 독자를 대상으로 스프링 부트의 기본

    www.yes24.com

     

Designed by Tistory.