'태그를 입력해 주세요.'에 해당되는 글 1건

  1. 2013.04.17 Spring profile 기능으로 운영/개발 환경 구성하기

Spring profile 기능으로 운영/개발 환경 구성하기



예제로 맨든 이클립스 프로젝트(maven project) SpringProfileSample.zip



스프링 3.1 부터 profile 기능이 추가됐다는 걸 어디서 쥬어듣고,


요걸 활용하면 기존에 내가 쓰던 maven의 profile 기능을 이용한 방법을 대체할 수 있을것 같은 생각이 들어 문득 이것저것 테스트해 보았다.


뭐 지금도 딱히 불편한것 없었지만 새로 추가된 기능이라 길래~~




먼저 운영/개발용 profile 을 작성하는 방법은 간단하다.

...
...
<beans profile="원하는 profile 이름1">
	<bean id="xxxx" class="xxxxxxx"/>
</beans>
<beans profile="원하는 profile 이름2">
	<bean id="xxxx" class="xxxxxxx"/>
	</bean>
</beans>
...
...


요런식으로 beans 태그 안에 각 profile 별로 bean 들을 추가해 주면 된다.





샘플로 맨든 프로젝트에서는 간단한 테스트를 위해 ProfileTestBean 이라는 클래스를 맨들고 요렇게 설정했다.


실제로 datasource 같은걸로 예제를 맨들어 보면 좋겠지만 이것저것 설정할게 많아서, 그러기엔 너무 귀찮다. 


테스트로 맨든 빈 대신에 datasource 를 넣으면 아마 잘 돌아가지 않을까 하는 추측을 해본다.


ProfileTestBean.java
package com.tistory.stove99;

public class ProfileTestBean {
	private String field1;
	private String field2;

	public String getField1() {
		return field1;
	}
	public void setField1(String field1) {
		this.field1 = field1;
	}
	public String getField2() {
		return field2;
	}
	public void setField2(String field2) {
		this.field2 = field2;
	}
	
	public String toString(){
		return String.format("{field1 : %s, field2 : %s}", field1, field2);
	}
}

spring 설정 xml

....
....
<beans profile="development">
	<bean id="mainBean" class="com.tistory.stove99.ProfileTestBean">
		<property name="field1" value="루트 컨텍스트-개발1"/>
		<property name="field2" value="루트 컨텍스트-개발2"/>
	</bean>
</beans>
<beans profile="product">
	<bean id="mainBean" class="com.tistory.stove99.ProfileTestBean">
		<property name="field1" value="루트 컨텍스트-운영1"/>
		<property name="field2" value="루트 컨텍스트-운영2"/>
	</bean>
</beans>
....
....


profile 은 원하는 이름으로 원하는 대로 맹글면 된다.


ProfileTestBean 을 @Autowired 하면 현재 active 된 profile 에 따라 등록된 bean 이 Autowired 된다.

@Autowired ProfileTestBean test;




아무튼 죠래 맨든 프로파일들중 원하는 프로파일을 어떻게 적용할 것인가에는 여러가지 방법이 있다.


JVM 변수 spring.profiles.active 요거에 적용할 profile 값을 주는방법


요렇게 spring.profiles.active 에 적용할 프로파일 이름을 적어주면 된다.




다른 방법으로는 웹어플리케이션일 경우 web.xml 파일에서도 요렇게 context-param을 이용해 설정할 수 있다.


그런데 배포할때 마다 web.xml 파일을 수정해야 될것 같아서 약간 거시기 하긴 하다.

<context-param>
	<param-name>spring.profiles.active</param-name>
	<param-value>product</param-value>
</context-param>


이외에도 DispatcherServlet에 init-param 으로 하는거와, 소스코드로 적용하는 방법등 몇가지 방법이 더 있는데 살짝 귀찮은 감이 없지 않아서 패스.






그렇다면 maven profile 에 비해 spring profile 을 이용하는 방법으로 바꿧을 때 좋아지는 점은 무엇일까 살짝 생각해 보았다.


뭔가가 좋아져야 적용할 필요성을 느낄것이 아닌가?


나의 짧은 생각으로 spring profile 로 바꿀만한 이유중 하나는 런타임시에도 profile 을 바꿀수 있다는 것이다.






개발을 하면서 요것저것 해보다가 음.. 운영환경에서는 쪽바로 나올까 하고 문득 궁금해 질때 로컬 서버를 굳이 껏다가 설정을 바꾸고 다시 안 켜도 바로 운영모드로 전환할 수 있다.


하는김에 만들어 보았다.




화면은 대충 요렇게 맨들었다.


오른쪽 위에 있는 노란부분을 클릭하면 운영/개발 모드로 토글되도록 맨들었다.



profile.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Profile Test</title>
		
		<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
		
		<style>
			#currentProfile{
				width:250px; height:50px; line-height:50px;
				position: absolute; top: 1px; right: 1px;
				border: 1px solid #d4c98a; background-color: #fff8d2;
				text-align:center; vertical-align: middle;
				font-size: 18pt;
				cursor: pointer;
			}
		</style>
	</head>
	
	<body>
		<div id="currentProfile">${ currentProfile } Mode</div>		
		
		<p>mainBean - ${ mainBean }</p>
		<p>subBean - ${ subBean }</p>
		
		<script>
			$("#currentProfile").on("click", function(){
				window.location.href = "/toggleProfile";
			});
		</script>
	</body>
</html>


ProfileController.java

package com.tistory.stove99.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.ConfigurableWebApplicationContext;

@Controller
public class ProfileController {
	@Autowired ConfigurableWebApplicationContext subContext;
	
	/**
	 * 현재 profile 보기
	 * @param model
	 */
	@RequestMapping("/profile")
	public void profile(Model model){
		model.addAttribute("currentProfile", currentProfile());
	}
	
	/**
	 * 운영/개발 profile 토글
	 * @return
	 */
	@RequestMapping("/toggleProfile")
	public String changeProfile(){
		String toChangeProfile = currentProfile().equals("product") ? "development" : "product";

		ConfigurableWebApplicationContext rootContext = (ConfigurableWebApplicationContext)subContext.getParent();
		
		
		// root, sub 싹다 엑티브 프로파일을 바꾼후 리프레쉬 해야 적용됨
		
		// Refreshing Root WebApplicationContext
		rootContext.getEnvironment().setActiveProfiles(toChangeProfile);
		rootContext.refresh();
		
		// Refreshing Spring-servlet WebApplicationContext
		subContext.getEnvironment().setActiveProfiles(toChangeProfile);
		subContext.refresh();
		
		return "redirect:/profile";
	}
	
	/**
	 * 현재 프로파일 가져오기
	 * @return
	 */
	private String currentProfile(){
		String[] profiles = subContext.getEnvironment().getActiveProfiles();
		
		if( profiles.length==0 ){
			profiles = subContext.getEnvironment().getDefaultProfiles();
		}
		
		return profiles[0];
	}
}


전체 소스는 죠 맨위에 있는 첨부파일을 받으면 됨. (메이븐 프로젝트)


그런데 요렇게 해도 될려나 몰라 -.-

prev 1 next