본문 바로가기
Web

레거시 스프링 프레임워크에서 환경변수를 주입받아서 properties를 관리하는 방법

by 모닝위즈 2024. 7. 23.
반응형

스프링부트에서 지원하는 환경분리의 개념을 레거시에도 도입하기 위함.

그래서 환경변수를 이용하려고 함.

 

# tomcat이 설치된 폴더 
# ex> /usr/local/tomcat/bin
cd /usr/local/tomcat/bin
vi setenv.sh

 

해당 파일 내용에 아래와 같은 내용 추가

#!/bin/bash
JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8 -Dspring.profiles.active=prod"
CATALINA_OPTS="$CATALINA_OPTS -Xms8g -Xmx24g"

 

개발툴인 Intellij에서는 아래처럼..

 

 

 

일단 위는 환경변수를 주입하는 과정이다.

 

이제부터는 이 환경변수를 받아서 처리하는 부분을 적으려고 함.

 

프로젝트에서 ApplicationInitializer.java 파일에 아래와 같이 작성

public class ApplicationInitializer implements WebApplicationInitializer {

	@Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        //TODO 환경변수를 받는다. 기본값은 prod
        String activeProfile = System.getProperty("spring.profiles.active", "prod");

        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(MybatisConfig.class);
        rootContext.register(SecurityConfig.class);
        rootContext.register(RedisConfig.class);
        servletContext.addListener(new ContextLoaderListener(rootContext));

        rootContext.getEnvironment().setActiveProfiles(activeProfile);
        this.dispatcherServlet(servletContext, activeProfile);

        System.out.println(":::::::::::: profiles active ::::::::::");
        System.out.println(activeProfile);
        System.out.println(":::::::::::::::::::::::::::::::::::::::");

        this.encodingFilter(servletContext);
        this.defaultServlet(servletContext);
    }

    private void dispatcherServlet(ServletContext servletContext, String activeProfile) {
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();

        //TODO 받은 환경변수의 값을 applicationContext에 등록
        applicationContext.getEnvironment().setActiveProfiles(activeProfile);

        applicationContext.register(WebMvcConfig.class);
        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("action", new DispatcherServlet(applicationContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
        dispatcher.setInitParameter("dispatchOptionsRequest", "true");
    }
    
    ... (생략) ...
}

 

 

위와 같이 설정해주면 해당 환경변수의 값을 어디서든 끌어다 쓸 수 있다. 

예제.

public class GetProperties {
	private static final Logger LOGGER = LoggerFactory.getLogger(GetProperties.class);
    //파일구분자
    final static String FILE_SEPARATOR = System.getProperty("file.separator");
    public static final String RELATIVE_PATH_PREFIX = GetProperties.class.getResource("").getPath().substring(0, GetProperties.class.getResource("").getPath().lastIndexOf("classes")) + "classes" + FILE_SEPARATOR;

    //TODO applicationContext에 등록된 환경변수의 값을 가져와서 적용
    static AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
    public static String GetGlobalsProperties() {
        String activeProfile =String.join(", ", applicationContext.getEnvironment().getActiveProfiles());
        activeProfile = activeProfile.equals("") ? "prod" : activeProfile;
        return RELATIVE_PATH_PREFIX + "/properties" + FILE_SEPARATOR + "globals-"+activeProfile+".properties";
    }
	public static final String GLOBALS_PROPERTIES_FILE = GetGlobalsProperties();
    
    
    /**
     * 인자로 주어진 문자열을 Key값으로 하는 프로퍼티 값을 반환한다(Globals.java 전용)
     *
     * @param keyName String
     * @return String
     */
    public static String getProperty(String keyName) {
        String value = "";
        String file = GLOBALS_PROPERTIES_FILE;
        LOGGER.debug("getProperty : {} = {}", file, keyName);
        FileInputStream fis = null;
        try {
            Properties props = new Properties();
            fis = new FileInputStream(EgovWebUtil.filePathBlackList(file));

            props.load(new BufferedInputStream(fis));
            if (props.getProperty(keyName) == null) {
                return "";
            }
            value = props.getProperty(keyName).trim();
        } catch (FileNotFoundException fne) {
            LOGGER.debug("Property file not found.", file);
            throw new RuntimeException("Property file not found", fne);
        } catch (IOException ioe) {
            LOGGER.debug("Property file IO exception", ioe);
            throw new RuntimeException("Property file IO exception", ioe);
        } finally {
            EgovResourceCloseHelper.close(fis);
        }

        return value;
    }
    
}

 

properties 파일을 분리된 환경에 따라 맞게 작성해둔다.

 

 

기존엔 globals.properties를 통으로 사용하고 해당 파일에 spring.profile.active=local 이렇게 파일에서 값으로 구분하는 방식은 좀 불편함이 있었다. 그래서 환경변수로 넘어가게 되었다. 

 

 

 

 

댓글