[Spring] 생성자 주입 다시 보기

snowballnote·2026년 9월 21일

한국도로공사 수집기를 추가하면서 G2bApiService 생성자도 수정했다.

실제 코드.

@Autowired
public G2bApiService(
        BidAwardMethodClassifier bidAwardMethodClassifier,
        List<BidCandidateCollector> additionalBidCandidateCollectors
) {
    this.bidAwardMethodClassifier = bidAwardMethodClassifier;
    this.additionalBidCandidateCollectors =
            List.copyOf(additionalBidCandidateCollectors);
}

생성자 주입

필요한 객체를 서비스 안에서 직접 new로 만드는 대신 생성자로 전달받는 방식.

private final BidAwardMethodClassifier classifier =
        new BidAwardMethodClassifier();

이렇게 직접 만들지 않고 Spring이 관리하는 Bean을 받아서 사용한다.

List<BidCandidateCollector>는 뭐가 들어오지?

List<BidCandidateCollector> additionalBidCandidateCollectors

Spring이 관리하는 Bean 중에서 BidCandidateCollector 타입에 해당하는 객체들을 모아서 주입한다.

Biz Assist에서는 한국도로공사 수집기가 이 인터페이스를 구현한다.

public interface BidCandidateCollector {

    List<BidQualificationDto> collect(
            LocalDate startDate,
            LocalDate endDate
    );
}

중요한 점.

implements BidCandidateCollector만 했다고 바로 들어오는 건 아니다.

Spring Bean으로 등록되어 있어야 한다.

실제 사용

for (BidCandidateCollector collector
        : additionalBidCandidateCollectors) {

    for (BidQualificationDto candidate
            : collector.collect(startDate, endDate)) {

        applyExternalCheckResult(candidate);
        applyAwardMethodClassification(candidate);
        applyReviewResult(candidate, normalizedCodes);

        addUniqueCandidate(uniqueCandidates, candidate);
    }
}

여기서는 수집기가 한국도로공사인지 다른 사이트인지 따로 확인하지 않는다.

그냥 collect()를 호출한다.

현재 나라장터는 기존 API 조회 흐름을 사용하고 BidCandidateCollector는 나라장터 외 추가 수집원을 연결하는 용도다.

@Autowired는 왜 붙였지?

Spring에서는 생성자가 하나면 @Autowired를 생략할 수 있다.

근데 G2bApiService에는 생성자가 세 개 있었다.

public G2bApiService() {
    this(new BidAwardMethodClassifier(), List.of());
}

public G2bApiService(
        BidAwardMethodClassifier bidAwardMethodClassifier
) {
    this(bidAwardMethodClassifier, List.of());
}

@Autowired
public G2bApiService(
        BidAwardMethodClassifier bidAwardMethodClassifier,
        List<BidCandidateCollector> additionalBidCandidateCollectors
) {
    ...
}

기존 테스트에서 직접 생성하는 코드가 있어서 다른 생성자도 남아 있었다.

그래서 Spring에서 사용할 생성자를 @Autowired로 지정했다.

List.copyOf()

this.additionalBidCandidateCollectors =
        List.copyOf(additionalBidCandidateCollectors);

전달받은 리스트를 수정할 수 없는 리스트로 복사한다.

수집기 목록은 실행 중에 바꿀 대상이 아니라서 이렇게 보관했다.

단 리스트 자체만 수정할 수 없는 것이고 내부 객체까지 불변이 되는 건 아니다.

이 글에서 다시 볼 건 이 정도.

생성자 주입
→ 필요한 객체를 외부에서 전달받음

List<BidCandidateCollector>
→ 같은 인터페이스 타입의 Spring Bean들을 주입

@Autowired
→ 여러 생성자 중 Spring이 사용할 생성자 지정

List.copyOf()
→ 수집기 목록 자체는 변경하지 않도록 보관
profile
개발자로 이 험난한 세상 살아가기

0개의 댓글