이 글은 인프런에서 김영한 님의 "스프링 핵심원리 - 기본편"을 수강 후 공부한 내용을 정리한 게시글입니다. 부족한 부분이 있다면 언제든 지적 부탁드립니다.
@Bean
이나 XML의 <bean>
를 통해서 직접 스프링 빈을 등록@ComponentScan
을 설정 클래스에 붙여준다.AppConfig
와는 다르게 @Bean
으로 등록한 클래스가 하나도 없다!AutoAppConfig.java
package hello.core;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import static org.springframework.context.annotation.ComponentScan.*;
@Configuration
@ComponentScan
public class AutoAppConfig {
}
@Component
어노테이션이 붙은 클래스를 스캔해서 스프링 빈으로 등록한다.@Component
어노테이션을 붙여주자.MemoryMemberRepository.java
@Component
public class MemoryMemberRepository implements MemberRepository {}
RateDiscountPolicy.java
@Component
public class RateDiscountPolicy implements DiscountPolicy {}
MemberServiceImpl.java
@Component
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
@Autowired
는 의존관계를 자동으로 주입해준다OrderServiceImpl.java
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
@Autowired
를 사용하면 생성자에서 여러 의존관계도 한번에 주입받을 수 있다@ComponentScan
@Autowired
의존관계 자동 주입
@ComponentScan(basePackages = "hello.core",}
basePackages
: 탐색할 패키지의 시작 위치를 지정한다. 이 패키지를 포함해서 하위 패키지를 모두 탐색한다.basePackages = {"hello.core", "hello.service"}
이렇게 여러 시작 위치를 지정할 수도 있다.basePackageClasses
: 지정한 클래스의 패키지를 탐색 시작 위치로 지정한다.@ComponentScan
이 붙은 설정 정보 클래스의 패키지가 시작 위치가 된다.@SpringBootApplication
를 이 프로젝트 시작 루트 위치에 두는 것이 관례이다. (그리고 이 설정안에 바로 @ComponentScan
이 들어있다!)컴포넌트 스캔은 @Component 뿐만 아니라 다음과 내용도 추가로 대상에 포함한다.
사실 애노테이션에는 상속관계라는 것이 없다. 그래서 이렇게 애노테이션이 특정 애노테이션을 들고 있는 것을 인식할 수 있는 것은 자바 언어가 지원하는 기능은 아니고, 스프링이 지원하는 기능이다.
ConflictingBeanDefinitionException
예외 발생@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy
discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
@Autowired
의 기본 동작은 주입할 대상이 없으면 오류가 발생한다. 주입할 대상이 없어도 동작하게 하려면 @Autowired(required = false)
로 지정하면 된다.@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Autowired
public void setDiscountPolicy(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
}
@Component
public class OrderServiceImpl implements OrderService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}
@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy
discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}