Spring Boot Enum 적용(Feat. Interface)

최민길(Gale)·2023년 6월 26일
1

Spring Boot 적용기

목록 보기
30/46

안녕하세요 오늘은 Spring Boot에서 Enum을 활용한 코드 리팩토링 작업을 진행해보겠습니다.

enum이란 열거형을 정의하는 키워드로, int 또는 문자열을 단순 나열하는 대신 enum을 통해 쉽게 관리할 수 있습니다. enum은 다음의 장점을 가집니다.

  1. 가독성 : 코드에서 사용하는 값을 의미있는 이름으로 표현 가능하기 때문에 가독성이 좋아집니다.
  2. type-safe : 열거형의 경우 해당 열거형에 속하는 값만 허용하기 때무네 잘못된 값이 들어오는 오류를 방지할 수 있습니다.
  3. 불변성 : 한 번 정의된 enum값은 변경할 수 없기 때문에 일종의 final class처럼 작동합니다. 따라서 thread-safe한 효과를 얻을 수 있습니다.

이런 장점을 프로젝트에 활용해보았습니다. 아래 보시는 부분은 Mdc 등록을 위한 enum 클래스입니다. MdcKeysExtender 인터페이스를 생성하여 enum 원소들이 가질 수 있는 여러 메소드를 정의합니다. 이를 통해 enum을 유연하게 확장하여 효율적인 객체 생성이 가능합니다. 아래 코드의 경우 mdc에 값을 추가, 삭제, 로그 출력을 하나의 enum 원소에 등록한 코드입니다. 클라이언트에서 이를 실행시키려면 REQUEST_ID.add(request) 이런 식으로 사용하면 가독성도 좋아지고 위에서 말씀드린 여러 장점들을 취할 수 있습니다.

public enum MdcKeys implements MdcKeysExtender {
    /**
     * - request_id : 로그 아이디
     * - request_context_path : 요청 path
     * - request_url : 요청한 url
     * - request_method : url method
     * - request_time : 요청 시간
     * - request_ip : 요청한 ip 주소
     * - request_header : 요청 헤더
     * - request_query_string : 요청 쿼리 스트링
     * - request_body : 요청 바디 (컨트롤러에서 벨리데이션 이후 추가)
     */

    REQUEST_ID{
        public void add(HttpServletRequest request){ MDC.put("request_id",UUID.randomUUID().toString()); }
        public void remove(){ MDC.remove("request_id"); }
        public void log(){ logger.info("request_id : " + MDC.get("request_id")); }
    },
    REQUEST_CONTEXT_PATH{
        public void add(HttpServletRequest request){ MDC.put("request_context_path", request.getContextPath()); }
        public void remove(){ MDC.remove("request_context_path"); }
        public void log(){ logger.info("request_context_path : " + MDC.get("request_context_path")); }
    },
    REQUEST_URL{
        public void add(HttpServletRequest request){ MDC.put("request_url", request.getRequestURI()); }
        public void remove(){ MDC.remove("request_url"); }
        public void log(){ logger.info("request_url : " + MDC.get("request_url")); }
    },
    REQUEST_METHOD{
        public void add(HttpServletRequest request){ MDC.put("request_method", request.getMethod()); }
        public void remove(){ MDC.remove("request_method"); }
        public void log(){ logger.info("request_method : " + MDC.get("request_method")); }
    },
    REQUEST_TIME{
        public void add(HttpServletRequest request){ MDC.put("request_time", new Date().toString()); }
        public void remove(){ MDC.remove("request_time"); }
        public void log(){ logger.info("request_time : " + MDC.get("request_time")); }
    },
    REQUEST_IP{
        public void add(HttpServletRequest request){ MDC.put("request_ip", request.getRemoteAddr()); }
        public void remove(){ MDC.remove("request_ip"); }
        public void log(){ logger.info("request_ip : " + MDC.get("request_ip")); }
    },
    REQUEST_HEADER{
        public void add(HttpServletRequest request){ MDC.put("request_header", request.getHeader(TokenProvider.HEADER_NAME)); }
        public void remove(){ MDC.remove("request_header"); }
        public void log(){ logger.info("request_header : " + MDC.get("request_header")); }
    },
    REQUEST_QUERY_STRING{
        public void add(HttpServletRequest request){ MDC.put("request_query_string", request.getQueryString()); }
        public void remove(){ MDC.remove("request_query_string"); }
        public void log(){ logger.info("request_query_string : " + MDC.get("request_query_string")); }
    };

    protected final Logger logger = LoggerFactory.getLogger(MdcKeys.class);
}
package com.toda.api.TODASERVERSPRINGBOOT.utils.extenders;

import jakarta.servlet.http.HttpServletRequest;

public interface MdcKeysExtender {
    void add(HttpServletRequest request);
    void remove();
    void log();
}
profile
저는 상황에 맞는 최적의 솔루션을 깊고 정확한 개념의 이해를 통한 다양한 방식으로 해결해오면서 지난 3년 동안 신규 서비스를 20만 회원 서비스로 성장시킨 Software Developer 최민길입니다.

0개의 댓글