한국도로공사 수집기를 추가하면서 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()
→ 수집기 목록 자체는 변경하지 않도록 보관