[SpringBoot] @Scheduled 어노테이션에서 상수 관련 오류

eunoia73·2025년 2월 21일

trouble shooting

목록 보기
14/16

1. 문제 개요

❗️문제 코드

    private static final Long PING_INTERVAL = 60 * 1000L; // 상수 선언
 	/**
     * 1분마다 자동으로 Ping 메시지 전송
     */
    @Scheduled(fixedRate = PING_INTERVAL)  // 1분마다 ping 전송
    public void scheduledPing() {
        sendBroadcastPing();
    }

❗️오류 상황:
SSE를 구현하는 과정에서, 클라이언트와 서버 간 연결을 유지하기 위해 1분마다 Ping 메시지를 전송하는 스케줄링 작업을 설정하던 중 문제를 발생
@Scheduled 어노테이션을 사용하여 작업을 실행하려고 했으나, 어노테이션의 fixedRate 속성에 전달된 값이 컴파일 타임 상수가 아니어서 오류 발생

2. 오류 코드 및 원인 분석

❗️오류 문구 : element value must be a constant expression
@Scheduled(fixedRate = PING_INTERVAL)

💡오류 원인:
60 * 1000L의 결과 타입은 long이므로, 래퍼 클래스인 Long 타입이 되려면 auto-boxing이 필요하다.
final 키워드가 붙어있으면 자동으로 boxing이 허용되지 않으므로 오류가 발생한다.

3. 해결방법

✅ 선택한 해결 방법

private static final long PING_INTERVAL = 60 * 1000L;

❓선택 이유
60 * 1000L의 결과값이 기본형 long 이므로 boxing이 필요 없다.
Long 객체를 생성하지 않으므로 메모리 효율성이 높다.


다른 해결 방법

1. 명시적 boxing

private static final Long PING_INTERVAL = Long.valueOf(60 * 1000L);

final이므로 auto-boxing이 적용되지 않기 때문에 명시적으로 설정 가능하다.
❗️Long.valueOf()를 사용하면 불필요한 객체 생성이 발생하여 메모리 낭비가 발생할 수 있다.

2. 따로 상수로 설정하지 않고 fixedRate에 직접 값을 입력한다.

@Scheduled(fixedRate = 60 * 1000L)  // 1분마다 ping 전송
    public void scheduledPing() {
        sendBroadcastPing();
    }

❗️하드코딩 방식이므로 fixedRate 값을 여러 곳에서 사용하면 유지보수가 어려워진다.

3. 프로퍼티 파일을 이용한 동적 설정

Spring Expression Language (SpEL) 사용하여 설정 가능

@Scheduled(fixedRateString = "${ping.interval}")
public void scheduledPing() {
        sendBroadcastPing();
    }

application.properties 파일

ping.interval = 5000

❗️값이 변경 가능해야 할 경우에 적합하지만, PING_INTERVAL은 변경되지 않는 상수이다.

❗️파일 의존성이 생긴다. 애플리케이션 실행 시 프로퍼티를 읽어와야 하므로, 설정 파일 없이 실행하면 오류 발생 가능.

✅ 결론

💡 상수 설정시에 기본형 (primitive type) 타입을 사용해야 한다!

private static final long PING_INTERVAL = 60 * 1000L;
  • 불필요한 boxing을 피할 수 있음 → Long 대신 long 사용하여 메모리 절약.
  • 가독성이 좋고 유지보수가 용이함 → 코드가 단순하고 직관적.
  • final로 고정된 값이므로 런타임 중 변경이 필요 없음 → 굳이 프로퍼티 파일을 사용할 필요 없음.
  • 상수이므로 필요하면 여러 곳에서 재사용 가능

    📌 단, 값이 동적으로 변경될 가능성이 있다면 application.properties 기반 설정도 고려 가능!

0개의 댓글