Spring Boot/기술

🧩 @Setter, set 메서드는 언제 사용하는걸까?

cyh0309 2025. 5. 24. 21:50

처음에는 “@Setter는 쓰지 말라고 하던데, 그런데 왜 어떤 코드는 쓰고 어떤 코드는 안 쓰는 거지?” 라는 생각이 들었습니다. 저처럼 의존성 주입은 무조건 생성자 방식이 좋다고 배워왔던 분들에게는 @Setter나 set 메서드의 존재가 헷갈릴 수 있습니다.

하지만 최근 프로젝트를 하면서 설정값을 다루는 @ConfigurationProperties 같은 클래스에서 setter 메서드를 직접 써야 하는 경우가 있었고, 그 이유를 공부하면서 정리가 필요하다고 느껴 이 글을 작성하게 되었습니다.

저처럼 '@Setter=안좋다'라고만 배웠던 분들에게 도움이 되길 바라며, 구체적으로 언제 사용하는지 살펴보겠습니다 😊


❓ 무조건 생성자 주입이 최고 아닌가?

보통 Spring에서는 불변성(immutability)명시적 의존성을 위해 생성자 주입을 권장합니다. 그래서 @Setter는 되도록 쓰지 말라고 배우죠.

그런데, 정말 모든 경우에 Setter는 안 쓰는 게 맞을까요?
사실 그렇진 않습니다.


🔍 설정값 주입에선 왜 Setter를 써야 할까?

예를 들어 application.yml에 이런 설정이 있다고 가정해볼게요

jwt:
  secret: abc123
  access-token-expiration: 3600

 

이 설정을 아래처럼 자바 코드에서 받으려면?

@Configuration
@ConfigurationProperties(prefix = "jwt")
@Getter
public class JwtConfig {
    private String secret;
    private long accessTokenExpiration;

    public void setSecret(String secret) {
        this.secret = secret;
    }

    public void setAccessTokenExpiration(long accessTokenExpiration) {
        this.accessTokenExpiration = accessTokenExpiration;
    }
}

 

여기서는 Spring이 객체를 생성하고, 내부적으로 setter를 통해 설정값을 주입합니다.
즉, 이 경우에는 생성자 주입을 사용할 수 없고, setter가 반드시 필요합니다.

✅ 이건 우리가 직접 new JwtConfig(...) 하는 게 아니라, Spring이 바인딩을 해주기 때문입니다.
* 바인딩(binding)은
- 어떤 데이터자바 객체의 필드에 연결해주는 행위
- 데이터를 객체에 넣는 자동화된 작업


@Setter, set 메서드를 써야 하는 경우 정리

상황 사용 여부 이유
@ConfigurationProperties 로 설정값 바인딩 ✅ 꼭 필요 Spring이 객체 생성 후 setter로 값을 주입
DTO 클래스 (조회용, 응답용) 상황에 따라 ⭕ 불변성보다는 편의성이 중요할 때
테스트용 Stub 객체 상황에 따라 ⭕ 빠른 설정과 유연한 조작 목적
일반 서비스/도메인 클래스 ❌ 피해야 함 생성자 주입으로 불변성, 명시성 확보

💡 왜 일반 서비스 코드에선 Setter를 피할까?

  • 값이 언제든지 바뀔 수 있어 불변 객체 설계가 어려워짐
  • 순환 참조나 테스트의 어려움을 만들 수 있음
  • 어떤 의존성이 필수인지 명시적으로 드러나지 않음

그래서 설정값 바인딩처럼 Spring 내부에서 자동으로 값을 넣어주는 특수한 경우가 아니라면, 웬만하면 생성자 주입을 사용하는 게 좋습니다.