본문 바로가기
CSE

[프로그래머스] ComponentScan, @Service

by bartizan_ 2023. 7. 19.
728x90

**컴포넌트 스캔

: 스프링이 직접 클래스를 검색해 빈으로 등록해 주는 기능. 설정 클래스에 빈으로 직접 등록하지 않아도 클래스를 빈으로 등록할 수 있다.

 

*흐름의 전반적 순서는 Controller -> Service -> Repository 순이다.

*Component : 독립적인 단위 모듈. 스프링부트에선 ioc 컨테이너에 등록된 클래스. @Component 어노테이션으로 작성한 클래스를 IOC에 등록한다. 여기서 IOC 컨테이너에 등록되어 ioc가 관리하는 객체를 bean이라고 한다. 

 

**@Service 어노테이션

: 클라이언트의 요청에 대한 비지니스 로직을 수행하는 컴포넌트.

 

 

VoucherService와 OrderService의 클래스에 @Service를 적어준다.

 

**

기존 AppConfiguration 클래스에서, voucherService와 orderService에 bean 어노테이션을 통해 구현했는데, 이 각각 클래스에 @Service 어노테이션을 적용시켜 앱 클래스에서 지우도록 구현했다.

 

그리고 구매 내역을 기억할 수 잇도록 바우처와 오더에 대한 메모리 레포지토리를 구현했다.

@Repository
public class MemoryVoucherRepository implements VoucherRepository {

//맵으로 바우처를 저장해보자
private final Map<UUID, Voucher> storage = new ConcurrentHashMap<>();
@Override
public Optional<Voucher> findById(UUID voucherId) {
return Optional.ofNullable(storage.get(voucherId));
//얘가 널 값일 수 있으니까.
}

@Override
public Voucher insert(Voucher voucher) {
storage.put(voucher.getVoucherID(), voucher);
return voucher;
}
}

위와 같이 구현햇으며, voucher레포지토리를 참조한다. CurrentHashMap으로 정보를 저장한다. 

 

그리고 오더 테스터에 바우처 레포지토리에 대한 값을 넣어준다. 

var voucherRepository = applicationContext.getBean(VoucherRepository.class);
var voucher = voucherRepository.insert(new FixedAmountVoucher(UUID.randomUUID(), 10L));

이를 통해 전에는 바우처가 있을 때와 없을 때 생성자 2개를 만들었는데, 메모리 바우처 레포에서 null 값을 다루니 필요가 없어 간단해졌다. 

var order =orderService.createOrder(customerId, new ArrayList<OrderItem>(){{
add(new OrderItem(UUID.randomUUID(), 100L, 1));
}}, voucher.getVoucherID());//voucher있을 수도, 없을 수도.

그래서 AppConfig 클래스는 텅 비었는데, 이제 여기서 컴포넌트 스캔을 적용한다. 주의할 점은 

@ComponentScan(basePackageClasses = {Order.class, Voucher.class})//얘도 넣어줘야 하죠?

위처럼 패키지에 대한 명시를 해줘야 다른 패키지에 있어도 값을 찾을 수 있다. **매우 중요한 것 같다.

 

 

728x90

댓글