쌩로그

[TroubleShooting] @Component 클래스에 시간 데이터는 필드로 넣지말고 메서드를 호출하는 방식을 사용하자. 본문

TroubleShooting & 고민

[TroubleShooting] @Component 클래스에 시간 데이터는 필드로 넣지말고 메서드를 호출하는 방식을 사용하자.

.쌩수. 2025. 3. 24. 16:04
반응형

목록

  1. 문제 발생 배경
  2. 문제 해결 방향
  3. 문제 해결
  4. 요약

1. 문제 발생 배경

회사 사내 그룹웨어가 있다.
각 직원마다 복지포인트가 주어진다.

매달 11일마다 복지포인트가 새로 쌓여서 갱신된다.

그런데, 1월 11일에 복지포인트가 갱신되지 않음과 동시에 백엔드로부터 받아온 데이터가 이상했다.

코드를 확인해보니..
@Component로 넣어놓은 클래스에 포인트를 계산하는 로직의 메서드가 있었고, 해당 메서드가 1월인지 아닌지에 따라 계산 방법이 틀려 if-else 처리되어 메서드를 호출한다.

이때 API를 호출하는 날짜가 언제인지는 클래스의 인스턴스 변수로 넣어놓은 LocalDate 타입의 값을 통해 계산되는데, 이 값이 문제였다.


왜 이 문제를 해가 바뀌고, 1월이 되었을 때야 발견했을까

1월이 아니면, 문제가 되지 않기 때문이다.
1월이냐 아니냐 라는 딱 두 가지 조건에 따라 포인트 계산이 바뀌었기 때문이다.
그래서 1월이 되어서야 해당 문제를 발견했다.


로그를 확인해봤을 때, 복지포인트를 계산하는 날짜 값이 오늘이 아니라, 2024년 12월 중에 있었다.
그럼 왜 12월 중으로 나와있었을까..?

사실 그 떄 무슨 일인지 모르겠지만,, 사내 서버를 한 번 내렸다가 올렸다.

2. 문제 해결 방향

코드를 예시로 들면 이렇게 되어있었다.


@Component
public class Util {

    private final today = LocalDate.now();
    ...
}

@Component 클래스는 스프링(부트) 애플리케이션이 실행될 때 ComponentScan을 통해서 Bean으로 등록되어 싱글톤 객체로 생명주기(LifeSycle)를 시작한다.

그래서 빈으로 등록된 동시에 LocalDate.now() 메서드가 호출되어 결과 값이 today 변수에 넣어졌고, 그 today는 시간이, 날이 지나가도 서버를 올린 날의 데이터가 저장되어있는 것이다

그래서 오늘의 날짜에 대한 데이터는 필드가 아니라, 매번 LocalDate.now()를 호출하도록 코드를 변경하면 해결할 문제다.

3. 문제 해결

위와 같은 코드를 아래와 같은 방식으로 변경했다.

@Component class Util {

    private static LocalDate today() {
        return LocalDate.now();
    }

    // today가 필요한 곳에 today 필드가 아니라, 아래와 같이 메서드를 불러오도록 한다.
    // calculation(today);
    calculation(today());
}

즉, 오늘 날짜가 필요할 때마다 메서드를 호출하는 방식으로 코드를 변경했다.

변수명은 그대로 가져가되... 메서드를 호출하는 방식으로 캡슐화해서 사용하도록했다.

4. 정리

@Component 클래스에 시간 데이터는 필드로 넣지말고 메서드를 호출하는 방식을 사용하자.

728x90
Comments