티스토리 뷰

프로젝트를 진행 시 phase(local, dev, prd..)에 따라 다른 resource를 바라봐야 할 때가 있다. 예를들면 DB 같은 경우이다. dev(개발)에서는 개발 DB를 바라보고 prd(운영)에서는 운영 DB를 바라봐야 한다. 이것뿐만 아니라 많은 설정들이 개발이냐 운영이냐에 따라 바뀌어야 한다. 이럴때 소스의 변경 없이 profile 으로 손쉽게 갈아끼울수 있다.
springboot에서는 어떻게 spring profile을 설정하는지 알아보자.


Spring Profile 설정방법 (application.yml)

server: port: 8080 servlet: context-path: / session: timeout: 1800 spring: datasource: driver-class-name: oracle.jdbc.OracleDriver url: jdbc:oracle:thin:@xx.xx.xx.xx:1521:OING username: oing password: daddy logging: pattern: console: "[%d{HH:mm:ss.SSS}][%-5level][%logger.%method:line%line] - %msg%n" level: org: INFO com: INFO --- spring: profiles: local --- spring: profiles: dev spring: datasource: driver-class-name: oracle.jdbc.OracleDriver url: jdbc:oracle:thin:@xx.xx.xx.xx:1521:OINGDEV username: oing password: daddy --- spring: profiles: prd spring: datasource: driver-class-name: oracle.jdbc.OracleDriver url: jdbc:oracle:thin:@xx.xx.xx.xx:1521:OINGPRD username: oing password: daddy

application.yml 에서 위와 같이 --- 로 구분을 지어 하나의 파일 안에서 phase를 분기할 수 있다. 맨 위의 설정은 application.yml 파일의 default 값이라고 보면 된다. 그 아래부터 --- 로 구분되어 local, dev, prd 등의 phase가 있다.
다른 phase에서 이 default 값을 override 하여 사용할 수 있다. 만약 위와 같이 log설정 부분은 default에 설정해 놓고 다른 phase에서는 설정하지 않는다면 모두 default에 설정한것이 적용된다.
datasource 같은 경우는 default에 정의하고 local phase에서는 정의하지 않았으면 local phase에서는 default에 정의한 datasource가 적용되고 나머지 재정의를 한 dev, prd에서는 재정의한 datasource가 적용된다.

Spring Profile 설정방법 (application.properties)

application.yml 으로 설정관리를 하는 경우는 위와 같이 spring profile을 정의할 수 있고 application.properties를 사용한다면 application-local.properties, application-dev.properties, application-prd.properties와 같은 식으로 파일을 만들어주면 spring profile이 jvm의 변수로 존재하면 자동으로 해당 파일을 인식을 한다.

application.properties profile 적용

꼭 application-xxx.properties 이런 식으로 파일명을 만들어 줘야 한다. application.yml 처럼 default가 있고 이를 override의 개념이 없으므로 각 파일에 모두 꽉꽉 채워서 작성해줘야 한다.

Spring Profile 설정방법 (applicationContext xml)

springboot에서는 거의 사용되지 않지만 xml로 config를 정의하는 경우는 다음과 같이 적용할 수 있다.

<beans profile="dev"> <bean id="datasourceConfig" class="oing.daddy.DatasourceConfig" /> </beans>

위와 같이 beans의 profile tag를 통해 profile을 적용할 수 있다.

Spring Profile 설정방법 (@Profile)

위와 같이 설정파일이 아닌 java source code 안에서도 phase에 따라 분기 처리를 하고 싶은 경우도 있다. 이럴 경우에 @Profile을 이용해서 분기처리를 할 수 있다.

@Profile("!prd") @Bean(name = "sqlSessionFactory") public SqlSessionFactory devSqlSessionFactory() throws Exception { SqlSessionFactoryBean factoryBean = new RefreshableSqlSessionFactoryBean(); factoryBean.setDataSource(oracleDataSource()); factoryBean.setVfs(SpringBootVFS.class); factoryBean.setConfigLocation(applicationContext.getResource("classpath:mybatis/mybatis-config.xml")); ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resource = resolver.getResources("classpath*:mybatis/oracle/**/*.xml"); factoryBean.setMapperLocations(resource); ((RefreshableSqlSessionFactoryBean) factoryBean).setInterval(1000); return factoryBean.getObject(); } @Profile("prd") @Bean(name = "sqlSessionFactory") public SqlSessionFactory sqlSessionFactory() throws Exception { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(oracleDataSource()); factoryBean.setVfs(SpringBootVFS.class); factoryBean.setConfigLocation(applicationContext.getResource("classpath:mybatis/mybatis-config.xml")); ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resource = resolver.getResources("classpath*:mybatis/oracle/**/*.xml"); factoryBean.setMapperLocations(resource); return factoryBean.getObject(); }

mapper xml 파일 변경시 reload를 하는 로직을 운영에서는 사용하지 않겠다는 코드이다. 위와 같이 @Profile 을 활용하여 spring profile을 적용할 수 있다.

  • @Profile("prd") > 운영시에만 사용하겠다.
  • @Profile("!prd") > 운영이 아닌 모든곳에서 사용하겠다.
  • @Profile({"local", "dev"}) > local과 dev phase에 사용하겠다.

대략 이정도만 알아도 @Profile로 정의를 할 수 있을 것이다.
필자와 같이 method에 @Profile을 정의할 수도 있고 class에도 @Profile을 정의할 수 있다. 사용방법은 마찬가지이다. 주의할점은 위에서 보다시피 method 명이나 class 명을 동일하게 생성 (만들어지지도 않는다.)하는 개념이 아니라 bean을 동일하게 생성한다는 개념으로 접근을 해야 한다.


Spring Profile 정의

여지껏은 어플리케이션에 spring profile을 설정하는 방법에 대해서 알아보았다. 그럼 이렇게 설정을 해놓기만 한걸 어디에서 어떻게 정의하여 사용하는지 알아보자.

WebApplicationInitializer, ConfigurableEnvironment, web.xml 등을 사용해서 '이 시스템은 profile 중 뭐를 사용할거다. ' 라고 선언할 수 있지만 적어도 필자가 겪었던 환경에서는 이와 같이 하는 경우는 거의 없었다. 다음과 같은 방법들을 주로 사용하였다.

바로 VM arguments-Dspring.profiles.active=dev 이런식으로 설정을 해주는 방법이다. IDE에서는 위와 같이 설정할 수 있고 springboot jar를 실행할때는 다음과 같이 설정을 해줄 수 있다.

$ java –jar sample-application.jar –Dspring.profiles.active=dev


아니면 OS 환경변수에 직접 세팅을 해주는 경우이다.

$ vi $HOME/.bashrc export SPRING_PROFILES_ACTIVE=prd $ $HOME/.bashrc


또한 위와 같이 실행 시점에 profile을 적용하는게 아닌 빌드 시점부터 profile을 적용하여 packing 할수도 있다.

mvn clean package -Pprd

maven에서는 위와 같이 package를 만들때 -P 옵션을 통해서 설정을 해줄 수 있다. 위와 같이 packing 하면 실행 시점에는 별도의 profile을 입력하지 않아도 된다.

spring profile이 여러개 동시에 선언이 되었다면 적용 우선순위는 다음과 같다.

  1. web.xml의 ContextParameter
  2. WebApplicationInitializer
  3. JVM system arguments
  4. OS 환경 변수
  5. Maven Profile

물론 이것처럼 여러개가 동시에 선언이 되게 하면 좋지 않다.


Spring Profile 가져오기

어플리케이션에 spring profile을 설정하고 시스템에 spring profile을 정의했다면 거의 다 된거지만 source code에서 현재 profile을 가지고 와서 처리를 해야할수도 있다. 위에 나온 것처럼 @Profile을 이용해서 처리할수도 있지만 더욱 심플하게 처리를 하고 싶은 경우에는 다음과 같은 방법들을 이용할 수 있다.

Environment getActiveProfiles() 를 이용하는 방법

public class ProfileManager { @Autowired private Environment environment; public void getActiveProfiles() { for (String profileName : environment.getActiveProfiles()) { System.out.println("Currently active profile - " + profileName); } } }

@Value("${spring.profiles.active}") 를 이용하는 방법

@Value("${spring.profiles.active}") private String activeProfile;

profile에 아무런 값을 넣지 않고 @Value로 값을 가져오면 오류가 발생한다.
default profile을 적용하기 위해 다음과 같이 한다.

@Value("${spring.profiles.active:}") private String activeProfile;

System.getProperty("spring.profiles.active") 를 이용하는 방법

String profile = System.getProperty("spring.profiles.active")

bean이 아니라 일반 java class에서는 위와 같은 방법으로 가지고 올 수 있다.

끝!

댓글
최근에 올라온 글
최근에 달린 댓글
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30