Fall in IT.

[Spring/Thymeleaf] 전역 유틸리티 함수를 사용하는 세 가지 방법 본문

프로그래밍언어/Java

[Spring/Thymeleaf] 전역 유틸리티 함수를 사용하는 세 가지 방법

D.Y 2025. 12. 26. 09:20
반응형

Thymeleaf를 사용하다 보면 Controller가 Model에 직접 담아주지 않은 데이터나, 공통적으로 사용하는 유틸리티 함수(날짜 포맷팅, 금액 변환 등)를 템플릿 어디에서나 자유롭게 호출하고 싶은 경우가 생깁니다.

단순히 데이터를 화면에 출력하는 것을 넘어, 템플릿의 가독성을 높이고 유지보수를 효율적으로 만들어주는 전역 유틸리티 활용법 3가지를 정리합니다.


1. Thymeleaf Expression Object (Custom Dialect)

Thymeleaf의 철학에 가장 부합하는 정석적인 방법입니다. 사용자가 직접 정의한 객체를 {#객체명} 형태로 사용할 수 있도록 등록하는 방식입니다.

구현 단계

  1. 유틸리티 서비스 작성: 실제 로직을 담당할 컴포넌트를 작성합니다.
  2. Dialect 및 Factory 구현: Thymeleaf 엔진이 인식할 수 있도록 IExpressionObjectDialect를 구현하여 등록합니다.
@Component
public class CustomThymeleafDialect extends AbstractDialect implements IExpressionObjectDialect {

    private final DateFormatUtils dateFormatUtils;

    public CustomThymeleafDialect(DateFormatUtils dateFormatUtils) {
        super("CustomDialect");
        this.dateFormatUtils = dateFormatUtils;
    }

    @Override
    public IExpressionObjectFactory getExpressionObjectFactory() {
        return new IExpressionObjectFactory() {
            @Override
            public Set<String> getAllExpressionObjectNames() {
                return Set.of("dateUtil"); // 템플릿에서 사용할 이름 (#dateUtil)
            }

            @Override
            public Object buildObject(IExpressionContext context, String name) {
                return "dateUtil".equals(name) ? dateFormatUtils : null;
            }

            @Override
            public boolean isCacheable(String name) { return true; }
        };
    }
}

템플릿 사용

<span th:text="${#dateUtil.format(order.createdAt, 'yyyy-MM-dd')}"></span>

2. Spring Bean 직접 접근 (@BeanName)

Spring 컨테이너에 등록된 Bean을 Thymeleaf에서 직접 호출하는 방식입니다. 별도의 설정 클래스 없이 가장 빠르게 적용할 수 있습니다.

템플릿 사용

<span th:text="${@dateFormatUtils.format(order.createdAt, 'yyyy-MM-dd')}"></span>
  • 특징: Bean 이름 앞에 @ 기호를 붙여 Spring Context 내의 객체에 접근합니다.

3. Static Utility 클래스 사용 (T(Class))

전형적인 Java 정적 메서드를 호출하는 방식입니다. Spring의 관리 범위 밖에 있는 일반 유틸리티 클래스에 유용합니다.

템플릿 사용

<span th:text="${T(com.example.util.DateUtil).format(order.createdAt)}"></span>
  • 특징: 클래스의 전체 패키지 경로(Full Qualifier)를 명시해야 합니다.

장단점 비교

구분 Thymeleaf Dialect Spring Bean 접근 Static 클래스

호출 문법 ${#dateUtil...} ${@dateUtil...} ${T(path.DateUtil)...}
추천 상황 프로젝트 표준 유틸 설정 시 빠른 개발이 필요할 때 단순 연산/상수 참조 시
장점 설계 의도에 명확히 부합, 가독성 우수 별도 설정 없이 즉시 사용 가능 Spring 의존성 없음
단점 구현 코드가 비교적 복잡함 View와 Service 계층 간 결합도 상승 패키지 경로 노출로 가독성 저하

정리

실무 프로젝트라면 1번(Custom Dialect) 방식을 권장합니다. # 기호를 통해 템플릿 전용 내장 객체임을 명시함으로써, 개발자가 "이 함수는 화면 렌더링을 위한 유틸리티구나"라고 직관적으로 파악할 수 있기 때문입니다.

반면, 특정 페이지에서만 임시로 기능을 수행해야 하거나 빠르게 기능을 확인해야 하는 경우에는 2번(Spring Bean 접근) 방식이 훌륭한 대안이 됩니다. 하지만 남용할 경우 템플릿에서 비즈니스 로직(Service)까지 접근할 위험이 있으므로 주의가 필요합니다.

반응형
Comments