ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스프링부트 profile 설정 (궁금증 해결. .properties / jvm 옵션 -Dspring/ web.xml의 init-param / System.setProperty() 등등)
    개발/Spring 2021. 3. 26. 14:23

    공부를 하면서 불편함과 해결되지 않은 궁금증이 있었다.

    1. (불편.귀찮) mysql로 개발을 하려면 매번 mysql를 켜줘야한다. 그게 귀찮아서 h2로 인메모리 db를 쓰려면 설정을 또 바꿔줘야 하는데 url, id, pw를 자꾸 까먹는다. 즉, mysql <-> h2 왔다갔다하는게 번거롭다.
    2. (모르겠는거) 스프링(이나 스프링부트)에 각종 설정이 많고 방법도 많아서 뭐가 뭔지 잘 모르겠고 헷갈린다.

    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):

    1. Default properties (specified by settingSpringApplication.setDefaultProperties).
    2. @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.
    3. Config data (such asapplication.propertiesfiles)
    4. ARandomValuePropertySourcethat has properties only inrandom.*.
    5. OS environment variables.
    6. Java System properties (System.getProperties()).
    7. JNDI attributes fromjava:comp/env.
    8. ServletContextinit parameters.
    9. ServletConfiginit parameters.
    10. Properties fromSPRING_APPLICATION_JSON(inline JSON embedded in an environment variable or system property).
    11. Command line arguments.
    12. propertiesattribute on your tests. Available on@SpringBootTestand thetest annotations for testing a particular slice of your application.
    13. @TestPropertySourceannotations on your tests.
    14. Devtools global settings propertiesin the$HOME/.config/spring-bootdirectory when devtools is active.

    Config data files are considered in the following order:

    1. Application propertiespackaged inside your jar (application.propertiesand YAML variants).
    2. Profile-specific application propertiespackaged inside your jar (application-{profile}.propertiesand YAML variants).
    3. Application propertiesoutside of your packaged jar (application.propertiesand YAML variants).
    4. 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.propertiesapplication-{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 옵션을 지정하는 방법이다.

    main() 클래스 이름을 클릭하고 Editt Configurations... 를 클릭한다.
    다음과 같은 창이 나오는데, Envinronment - VM options 에 'java'는 빼고 옵션만 지정하면 된다.

     

     

    자바 코드로 시스템 프로퍼티 지정

    @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)

    댓글

Designed by Tistory.