-
스프링부트 profile 설정 (궁금증 해결. .properties / jvm 옵션 -Dspring/ web.xml의 init-param / System.setProperty() 등등)개발/Spring 2021. 3. 26. 14:23
공부를 하면서 불편함과 해결되지 않은 궁금증이 있었다.
- (불편.귀찮) mysql로 개발을 하려면 매번 mysql를 켜줘야한다. 그게 귀찮아서 h2로 인메모리 db를 쓰려면 설정을 또 바꿔줘야 하는데 url, id, pw를 자꾸 까먹는다. 즉, mysql <-> h2 왔다갔다하는게 번거롭다.
- (모르겠는거) 스프링(이나 스프링부트)에 각종 설정이 많고 방법도 많아서 뭐가 뭔지 잘 모르겠고 헷갈린다.
1번 문제를 해결하려고 책을 보다보니 2번 문제가 어느정도 해결이 되었다.
설정 하는 방법들, 우선순위
스프링부트에는 각 목적에 따라 설정을 달리할 수 있는 Profile 이라는 기능을 제공한다.
Profile은 이름을 지정해서 설정 자바 코드나 프로퍼티를 작성하고 지정한 Profile 이름을 통해 설정을 읽어들일 수 있다.
즉, h2-인메모리db 를 사용해서 개발을 하다가 mysql로 왔다갔다를 '이름만 지정해서' 아주 손쉽게 실수없이 할 수 있다.
설정은 다음 같은 순서로 읽어들이고 그만큼 많은 설정 방법이 있다는 뜻이기도 하다. (뒤에 있는 설정 늦게 읽히므로 우선순위가 높다)
(docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config)
Spring Boot uses a very particularPropertySourceorder that is designed to allow sensible overriding of values. Properties are considered in the following order (with values from lower items overriding earlier ones):- Default properties (specified by settingSpringApplication.setDefaultProperties).
- @PropertySourceannotations on your@Configurationclasses. Please note that such property sources are not added to theEnvironmentuntil the application context is being refreshed. This is too late to configure certain properties such aslogging.*andspring.main.*which are read before refresh begins.
- Config data (such asapplication.propertiesfiles)
- ARandomValuePropertySourcethat has properties only inrandom.*.
- OS environment variables.
- Java System properties (System.getProperties()).
- JNDI attributes fromjava:comp/env.
- ServletContextinit parameters.
- ServletConfiginit parameters.
- Properties fromSPRING_APPLICATION_JSON(inline JSON embedded in an environment variable or system property).
- Command line arguments.
- propertiesattribute on your tests. Available on@SpringBootTestand thetest annotations for testing a particular slice of your application.
- @TestPropertySourceannotations on your tests.
- Devtools global settings propertiesin the$HOME/.config/spring-bootdirectory when devtools is active.
Config data files are considered in the following order:
- Application propertiespackaged inside your jar (application.propertiesand YAML variants).
- Profile-specific application propertiespackaged inside your jar (application-{profile}.propertiesand YAML variants).
- Application propertiesoutside of your packaged jar (application.propertiesand YAML variants).
- Profile-specific application propertiesoutside of your packaged jar (application-{profile}.propertiesand YAML variants).
Profile(설정) 작성하기
설정을 작성하는 방법은 크게 두가지다.
- 자바 코드로 작성하는 방법
- properties 로 작성하는 방법
자바 코드
@Configuration @Profile("dev") public class DevConfig { @Bean public DataSource dataSource() { DataSource ds = new DataSource(); ds.setUrl("jdbc://mysql://localhost/spring5fs?characterEncoding=utf8"); ds.setUsername("spring5"); ds.setPassword("spring5"); return ds; } }
bean 을 작성하는 설정 클래스를 만들고 @Profile 어노테이션에 이름만 지정해주면 된다.
Properties
// 파일 이름 : application-prod.properties spring.datasource.url=jdbc://mysql://localhost/spring5fs?characterEncoding=utf8 spring.datasource.username=spring5 spring.datasource.password=spring5
스프링부트에서는 application.properties 와 application-{profile_name}.properties 를 설정 파일로 인식한다.
그에맞게 .properties 설정 파일을 생성하면 된다.
{profile_name} 가 작성한 Profile 의 이름이 된다.
Profile 읽어오기(선택하기)
앞에서 자바코드나 .properties로 만든 Profile 을 선택하려면 여러가지 방법이 있는데
모든 결론은 spring.profiles.active 이라는 시스템 프로퍼티나 환경변수를 바꾸어주면 된다.
(환경변수로 설정하려면 SPRING_PROFILES_ACTIVE. 환경변수로 설정은jsonobject.tistory.com/220 를 참고)
시스템 프로퍼티 : https://coding-factory.tistory.com/527
시스템 프로퍼티는 JVM이 시작할 때 자동으로 설정되는 시스템 속성값입니다. 시스템 프로퍼티는 키(key)와 값(value)로 구성되어 있으며 운영체제에서 사용되는 파일 경로, 구분자, 운영체제의 종류 및 자바 프로그램을 실행시킨 사용자 아이디 JVM의 버전등이 여기에 속합니다.JVM 옵션으로 지정 (커맨드 명령)
java -Dspring.profiles.active=프로파일\_이름
으로 지정해줄 수 있다.다음은 인텔리제이로 JVM 옵션을 지정하는 방법이다.
자바 코드로 시스템 프로퍼티 지정
@SpringBootApplication public class App { public static void main(String[] args) { System.setProperty("spring.profiles.active", "dev"); SpringApplication.run(App.class, args); } }
자바에서는 java.lang.System 클래스의 setProperty() 메소드 를 통해 설정을 할 수 있다.
여기서 순서가 중요하다. 위에서 언급한 스프링부트의 프로퍼티를 읽는 순서에 따르면 기본설정 -> ... -> System.getProperties() 이다.
스프링부트를 run() 하기전에 시스템 프로퍼티를 미리 설정해야 스프링부트를 run 했을 때 기본설정을 읽은 뒤 나중에 시스템 프로퍼티를 제대로 읽어들일 것이다. (만약 순서를 바꿔서 스프링부트가 설정을 이미 다 읽어들인 뒤 ,시스템 프로퍼티를 설정하면 아무 의미가 없다.)
application.properties 에서 지정
위와 같이 기본 application.properties 가 있고 'prod' 라는 이름을 가진 profile 용 properties 가 있을 때
# 파일 : application.properties spring.profiles.active=prod
끝. 간단하다.
web.xml 에서 파라미터 이용
스프링부트를 사용하면서 web.xml 을 (나는) 사용하지 않게 되었는데, 스프링을 처음 시작했을 때 이 web.xml 에 무엇을 넣어야하는지 모르겠고 너무 어렵게 보였다.
그런데 spring.profiles.active 같은 시스템 프로퍼티를 이 web.xml 에서 설정할 수 있다! (는 것을 알았다.)
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>spring.profiles.active</param-name> <param-value>dev</param-value> </init-param> </servlet>
<init-param> 태그 안에 에 파라미터 이름과 값을 지정해주면 된다.
(다음에 더 알아볼 내용 - @ConfigurationProperties , @Value)