이전 포스팅에서 스프링 빈을 등록할 때는
자바 코드의 @Bean이나 XML의 등을 통해서 설정 정보에 직접 등록할 스프링 빈을 나열했다.
만약 등록해야 할 스프링 빈이 수백 개가 된다면
자바 코드를 통해서 스프링 빈을 생성하는게 여간 쉬운 일이 아니다.
그래서 스프링은 설정 정보가 없어도 자동으로 스프링 빈을 등록하는
컴포넌트 스캔이라는 기능을 제공한다.
또 의존관계도 자동으로 주입하는 @Autowired 라는 기능도 제공한다.
코드로 컴포넌트 스캔과 의존관계 자동 주입을 알아보자.
먼저 기존 AppConfig.java는 아래와 같다.
AppConfig.java
package hello.core;
import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.discount.RateDiscountPolicy;
import hello.core.member.MemberRepository;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean // 스프링 컨테이너에 등록이 됨
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public DiscountPolicy discountPolicy() {
return new RateDiscountPolicy();
}
}
이렇게 등록해야 할 빈이 많지 않다면, 빈을 생성하는 것은 어렵지 않다.
하지만 그 수가 많아진다면 일일이 빈을 등록해야 하는 점이 불편하다.
@ComponentScan
이제 컴포넌트 스캔 방식으로 빈을 생성해보자.
먼저 스프링 설정 정보인 @Configuration을 생성하자.
AutoAppConfig.java
package hello.core;
import hello.core.member.MemberRepository;
import hello.core.member.MemoryMemberRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
@Configuration
// @Component 애노테이션이 붙은 클래스를 찾아서 자동으로 스프링 빈 등록
@ComponentScan(
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class) // 스캔에서 제외할 것
)
public class AutoAppConfig {
}
컴포넌트 스캔을 사용하려면 먼저 @ComponentScan을 설정 정보에 붙여주면 된다
컴포넌트 스캔을 사용하면 @Configuration 이 붙은 설정 정보도 자동으로 등록되기 때문에,
AppConfig, TestConfig 등 앞서 만들어두었던 설정 정보도 함께 등록되고, 실행되어 버린다.
그래서 excludeFilters를 이용해서 설정 정보는 컴포넌트 스캔 대상에서 제외했다.
컴포넌트 스캔은
이름 그대로 @Component 애노테이션이 붙은 클래스를 스캔해서 스프링 빈으로 등록한다.
스프링 빈으로 등록하고자 할 클래스들에 @Component 를 붙여주자.
MemoryMemberRepository @Component 추가
@Component
public class MemoryMemberRepository implements MemberRepository {
}
이런 식으로 등록하고자 할 클래스 상단에
@Component를 입력해주면 된다.
@Autowired
이전에 스프링 빈을 자바 코드로 등록했던 설정을 보면
@Bean // 스프링 컨테이너에 등록이 됨
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
memberServiceImpl 빈 객체를 생성하면서
memberRepository 빈과 의존관계가 설정이 되었다.
그렇다면 컴포넌트 스캔 방식에선 어떻게 의존관계를 연결해줄까?
스프링에서는 @Autowired를 제공해준다.
예시로 MemberServiceImpl 클래스를 살펴보자.
MemberServiceImpl.java
package hello.core.member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component // componentScan에 의해 component로 등록
public class MemberServiceImpl implements MemberService{
private final MemberRepository memberRepository;
// ComponentScan시 의존관계 자동 주입
@Autowired // ac.getBean(MemberRepository.class)
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Override
public void join(Member member) {
memberRepository.save(member);
}
@Override
public Member findMember(Long memberId) {
return memberRepository.findById(memberId);
}
}
클래스가 호출될 때, 생성자를 통해서 memberRepository의 사용을 알리고
@Autowired 코드를 생성자 상단에 작성하여 의존관계를 자동으로 주입해준다.
정리하자면,
@ComponentScan은
@Component 가 붙은 모든 클래스를 스프링 빈으로 등록한다.
생성자에 @Autowired 를 지정하면,
스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 주입한다.
'Java > Spring' 카테고리의 다른 글
[Spring] 의존관계 주입 방법(@Autowired) | 생성자 주입 | 수정자 주입(setter 주입) | 필드 주입 | 일반 메서드 주입 (0) | 2022.01.24 |
---|---|
[Spring] 스프링 필터(Spring Filter) | FilterType 옵션 (0) | 2022.01.22 |
[Spring] 싱글톤 방식의 주의점 | 무상태(stateless) (0) | 2022.01.21 |
[Spring] 싱글톤 패턴(Singleton Pattern)의 문제점과 스프링 컨테이너 (0) | 2022.01.21 |
[Spring] 싱글톤(Singleton) 이란? | 싱글톤 패턴 | 싱글톤 컨테이너 | 웹 애플리케이션과 싱글톤 |Singleton Pattern | Singleton Container (0) | 2022.01.21 |