-
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. 우선 순위
- 프로퍼티 지정의 우선 순위는 다음과 같다.
- 명령행 인자
- 운영체제 환경 변수
- 설정 정보 파일
- @PropertySource
- 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 애너테이션을 사용해서 등록하거나, 하지 않을 수 있다.
[Spring] 스프링 @Profile 어노테이션을 통한 환경 설정(Spring Environment Configuration, @Profile)
| 스프링 환경설정(Spring Environment Configuration) 스프링에서는 프로필(Profile)을 통해 런타임 환경을 설정할 수 있는 기능을 제공한다. 이 기능을 이용하여 테스트환경에서 여러 테스트를 돌리고 난
engkimbs.tistory.com
https://www.yes24.com/Product/Goods/122002340
실전 스프링 부트 - 예스24
인류에겐 이런 스프링 부트 가이드북이 필요했다방대한 스프링 부트 공식 문서 중 실무에서 잘 쓰이는 팁을 찾기란 어렵다. 이 책은 초급에서 중급 수준의 독자를 대상으로 스프링 부트의 기본
www.yes24.com
'Web > 환경설정 관련' 카테고리의 다른 글
스프링 부트 구성 - @Import, @Conditional 활용 (0) 2024.05.13 스프링 부트 애플리케이션 시작 시 코드 실행 (CommandLineRunner) (0) 2024.05.10 Spring boot - 정적 리소스 설정 변경 (0) 2024.05.10 웹 어플리케이션 배포 (0) 2023.07.22 Eclipse에서 Web개발을 위한 환경설정 (0) 2023.05.20