▸Spring MVC/기본 문법

스프링에서 외부 환경 변수 정보 읽어오기 (Properties 파일)

코데방 2020. 3. 9.
728x90
- Develop OS : Windows10 Ent, 64bit
- WEB/WAS Server : Tomcat v9.0
- DBMS : MySQL 5.7.29 for Linux (Docker)
- Language : JAVA 1.8 (JDK 1.8)
- Framwork : Spring 3.1.1 Release
- Build Tool : Maven 3.6.3
- ORM : Mybatis 3.2.8

 

코드 내에 정보를 넣어 두지 않고 외부 설정 파일을 이용해 정보를 주입시켜주는 방식입니다. 빈(Bean)과 마찬가지로 코드를 변경하지 않고도 쉽게 정보를 수정할 수 있다는 장점이 있습니다.

 

예를 들어 프로그램에서 환경 설정 탭에 들어가 DB 정보를 입력하면 해당 DB와 연동되도록 만들 수 있는데, 이 정보를  메모리에 그냥 보관을 하게 되면 서버가 재부팅된다거나할 때 설정 정보다 모두 날아가게 됩니다. 이 때 입력한 정보를 외부 파일로 저장해 프로그램이 로드될 때나 버튼을 눌렀을 때 주입하도록 한다면 설정 정보가 계속 보관될 수 있습니다. 혼자 개발할 때는 불필요해 보일 수 있지만 시스템 운영을 생각하면 필수적인 기능입니다.

 

이번 글에서 다룰 내용은 자바의 기본 문법에서 한 번 다뤘던 Properties 파일을 이용해 정보를 저장한 뒤 다시 프로그램에서 읽어오는 방법입니다. 스프링의 빈(Bean) 개념과 함께 쓰면 생성과 동시에 환경 변수를 편하게 가져올 수 있습니다.

 

 


 

 

[ Properties 파일 생성 및 작성 ]

 

프로퍼티 파일은 딱히 xml처럼 여러 가지 설정 정보들이 들어가지 않기 때문에 그냥 메모장으로 만들어도 되고 이클립스에서 만들어도 됩니다. 확장자만 properties로 해주면 됩니다. 일단 이클립스에서 파일을 하나 생성하겠습니다.

 

 

 

 

그리고 아래와 같은 형식으로 작성해주면 됩니다. 왼쪽이 프로퍼티의 이름이 되고 오른쪽이 값입니다.

 

 

 


 

 

[ 코드에서 Properties 파일에서 설정 정보 가져오기 ]

 

먼저 빈(Bean)을 사용하지 않고 코드 내에서 외부의 프로퍼티 정보를 가져오는 방법입니다.

 

외부 리소스를 관리하는 객체가 컨테이너이기 때문에 먼저 컨테이너를 생성합니다. 그리고 컨테이너에서 환경변수를 관리해주는 객체를 생성하고 또 거기서 프로퍼티를 관리하는 객체를 생성해 파일을 등록해줍니다. 그리고 다시 환경변수 관리 객체에서 프로퍼티에 등록된 정보를 읽어옵니다.

 

클래스 구조와 코드가 꽤 복잡하니 그냥 필요할 때 찾아서 쓰는게 좋을 것 같습니다. 사실 스프링 빈을 사용해서 정보를 가져오는게 편해서 굳이 코드 내에서 쓸 일이 있을까 싶기도 합니다. 스프링은 IOC(제어의 역전) 개념이 짱짱한 프레임워크니까요. ㅎㅎ

 

package com.hsweb.springweb;

import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.io.support.ResourcePropertySource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class HomeController {
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Model model) throws Exception {
	
		// 컨테이너 생성
		GenericXmlApplicationContext ctx 
				= new GenericXmlApplicationContext();
		
		// 환경변수 관리 객체 생성
		ConfigurableEnvironment env = ctx.getEnvironment();
		
		// 프로퍼티 관리 객체 생성
		MutablePropertySources prop = env.getPropertySources();
		
		// 프로퍼티 관리 객체에 프로퍼티 파일 추가
		prop.addLast
			(new ResourcePropertySource("classpath:test.properties"));
		
		// 프로퍼티 정보 얻기
		String ip = env.getProperty("ip");
		String hostName = env.getProperty("hostName");
		
		System.out.println(ip + " : " + hostName);
		
		return "home";
	}
}

 

 

 


 

 

[ 빈(Bean) 설정 파일에서 프로퍼티 정보 가져오기 ]

 

다음은 스프링 빈(Bean)을 설정 시에 좀 더 수월하게 프로퍼티 정보를 가져와 사용할 수 있는 방법입니다. 환경변수를 관리할 전용 클래스를 따로 만들어 빈으로 만들어서 사용하면 위 방법보다 훨씬 가시성도 좋고 관리도 편할 것 같습니다.

 

방법은 빈을 만들 때 필드의 초기 값을 전달해주는 것과 동일합니다. 다만 프로퍼티 파일을 추가로 설정해줘야 합니다.

 

1. 빈 설정 xml 파일에 프로퍼티 파일 주입

 

먼저 아래 코드를 넣어줍니다. 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!-- 프로퍼티 파일 삽입 (여러개면 콤마로 구분해서 한번에 넣어줄 수 있음) -->
	<context:property-placeholder
		location="classpath:test.properties" />

</beans>

 

 

이클립스에서 기본 설정된 Spring Bean Configuration File이라면 빨간줄이 생기면서 오류가 납니다. 스키마를 어디서 가져올지 명시가 되어 있지 않아서인데, 이 경우 직접 코드를 넣기 보다는 아래와 같이 설정해주면 이클립스가 자동으로 해결해줍니다.

 

아래에 보이는 "Namespaces" 탭을 열어 "context"에 체크를 해줍니다. 혹시 Namespaces 탭이 보이지 않는다면 xml 파일을 열 때 우클릭 해서 'Spring Config Editor'로 열어주면 됩니다.

 

Namespaces 탭이 안보일 때

 

 

 

위와 같이 셋팅했다면 빨간줄이 없어지면서 프로퍼티 정보를 읽어올 수 있는 상태가 됩니다. 

 

 

 

2. 빈 정의와 초기 필드 값 셋팅

 

이전글에서 다룬 내용과 동일합니다. 생성자로 넣어도 되고 setter 메소드를 사용해도 무방합니다. 다만 전달할 값이 하드코딩이 아닌 프로퍼티 파일에서 가져오도록 해주는 것만 다릅니다. 아래 코드를 보시면 직관적으로 이해할 수 있습니다. 대상 클래스의 코드와 빈 설정 파일 코드입니다.

 

package com.hsweb.springweb;

public class Test {

	private String ip;
	private String hostName;

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public String getHostName() {
		return hostName;
	}

	public void setHostName(String hostName) {
		this.hostName = hostName;
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context-3.1.xsd">

	<!-- 프로퍼티 파일 삽입 (여러개면 콤마로 구분해서 한번에 넣어줄 수 있음) -->
	<context:property-placeholder
		location="classpath:test.properties" />

	<!-- 빈 생성 및 setter 매개변수 전달 -->
	<bean id="test" class="com.hsweb.springweb.Test">
		<property name="ip">
			<value>${ip}</value>
		</property>

		<property name="hostName">
			<value>${hostName}</value>
		</property>
	</bean>
</beans>

 

 

 

3. 컨테이너에서 빈 객체 받아와서 사용

 

위의 과정을 수행했다면 이제 빈(Bean) 객체는 생성될 때 setter 메소드를 실행해 xml에서 정의해둔 매개변수로 필드에 값을 넣어준 상태가 됩니다. 오류 없이 빈이 초기화됐다면 프로퍼티 파일 여부에 관계 없이 빈이 가진 정보라고 생각하고 사용하면 됩니다.

 

package com.hsweb.springweb;

import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class HomeController {
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Model model) throws Exception {
	
		// 컨테이너 생성 및 xml 파일 로드
		GenericXmlApplicationContext ctx 
				= new GenericXmlApplicationContext();
		ctx.load("classpath:appCTX.xml");
		ctx.refresh();
		
		// 빈 객체 받아오기
		Test test = (Test)ctx.getBean("test");
		
		// 프로퍼티 값 확인
		System.out.println(test.getIp());
		System.out.println(test.getHostName());
		
		return "home";
	}
}

 

 

 

참고로 자동 의존성 주입(@Resources, @Inject, @Autowired)을 사용할 때는, xml 파일에 프로퍼티 파일만 삽입해두고 클래스 내에서 @value(${value}) 어노테이션을 통해 프로퍼티값을 주입받을 수 있습니다.

728x90

댓글

💲 추천 글