이번에는 Autowired를 사용해보겠다.
@Configuration
@ComponentScan(
//해당 위치에서부터 찾는다. (안해도됨)
basePackages = "com.example.ramen",
//AutoWireConfig가 해당되어 있는 com.example.ramen패키지에서도 찾는다. (안해도됨)
basePackageClasses = AutoWireConfig.class,
//Configuration내부에는 Component가 이미 있다. 그러므로 자동으로 넣다가 충돌할 염려가 있으므로 막아주는 역할을 한다.
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class)
)
public class AutoWireConfig {
}
그리고 각 객체마다 @Component를 붙여주면 된다.(인터페이스X)
예시로
@Component // <----------이렇게 붙이면 된다.
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Override
public void join(Member member) {
memberRepository.save(member);
}
@Override
public Member findMember(Long memberId) {
Member member = memberRepository.findById(memberId);
return member;
}
}
이렇게
MemberServiceImpl
OrderServiceImpl
MemoryMemberRepository
RateDiscountPolicy에 @Component를 붙였다.
그리고 테스트를 해보겠다.
Autowired
수동 Bean
Map으로 빼서 등록하는것들을 출력하겠다.
//자동으로 빈을 등록할 경우 못찾을 때 해당 어노테이션을 쓰면 된다.
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@SpringBootTest
public class AutowiredTest {
@Autowired
MemberRepository memberRepository;
@Autowired
DiscountPolicy discountPolicy;
@Autowired
MemberService memberService;
@Autowired
OrderService orderService;
@Test
@DisplayName("메뉴에 들어가는지 테스트")
public void test() {
ApplicationContext passivityAc = new AnnotationConfigApplicationContext(BeanConfig.class);
MemberRepository memberRepository = passivityAc.getBean(MemberRepository.class);
DiscountPolicy discountPolicy = passivityAc.getBean(DiscountPolicy.class);
//구현타입을 그대로 써도 됨(하지만 SOLID가 깨지므로 비추천)
MemberService memberService = passivityAc.getBean(MemberServiceImpl.class);
OrderService orderService = passivityAc.getBean(OrderService.class);
Map<String, MemberRepository> memberRepositoryBeansOfType = passivityAc.getBeansOfType(MemberRepository.class);
Map<String, DiscountPolicy> discountPolicyBeansOfType = passivityAc.getBeansOfType(DiscountPolicy.class);
Map<String, MemberService> memberServiceBeansOfType = passivityAc.getBeansOfType(MemberService.class);
Map<String, OrderService> orderServiceBeansOfType = passivityAc.getBeansOfType(OrderService.class);
System.out.println("passivityAc memberRepository : " + memberRepository.getClass());//수동 Bean으로 받은 멤버 변수
System.out.println("Auto memberRepository : " + this.memberRepository.getClass());//Autowired로 받은 멤버 변수
System.out.println("inquiry memberRepository : " + memberRepositoryBeansOfType.get("memberRepository").getClass());
System.out.println("passivityAc discountPolicy : " + discountPolicy.getClass());
System.out.println("Auto discountPolicy : " + this.discountPolicy.getClass());
System.out.println("inquiry discountPolicy : " + discountPolicyBeansOfType.get("discountPolicy").getClass());
System.out.println("passivityAc memberService : " + memberService.getClass());
System.out.println("Auto memberService : " + this.memberService.getClass());
System.out.println("inquiry memberService : " + memberServiceBeansOfType.get("memberService").getClass());
System.out.println("passivityAc orderService : " + orderService.getClass());
System.out.println("Auto orderService : " + this.orderService.getClass());
System.out.println("inquiry orderService : " + orderServiceBeansOfType.get("orderService").getClass());
}
}
이렇게 나온다.
그리고 수동이든 자동이든 빈에 등록된 객체들(MemberServiceImpl, OrderServiceImpl, MemoryMemberRepository, RateDiscountPolicy)은 싱글톤이 된다.
그리고 @Qualifier이라는 어노테이션이 있다.
빈에 등록된것들 중 하나를 가져오고 싶다면 쓰면된다.
만약 RateDiscountPollicy가 아닌 FixDiscountPolicy를 쓰고싶다면
@Component
@Qualifier("fixDiscountPolicy")
class FixDiscountPolicy {
.......
}
@Component
@Primary
class RateDiscountPolicy {
.......
}
class Test{
@Autowired
@Qualifier("fixDiscountPolicy")
public void testMethod(DiscountPolicy discountPolicy) {
.....
}
}
이렇게 하면 testMethod()의 파라미터에는 RateDiscountPolicy가 아닌 FixDiscountPolicy가 될 것이다.
그런데 왜 RateDiscoutPolicy에 @Primary를 추가했냐하면
@Primary 어노테이션은 "이 빈을 기본 설정으로 쓸것이다" 라고 하는것과 마찬가지이다
만약 @Primary가 없는 상태에서 FixDiscountPolicy와 RateDiscountPolicy를 DiscountPolicy.class 타입으로 가져가려 한다면
둘 중 어느것을 가져가야 할 지 몰라 에러를 터뜨리고 만다.
'Spring 공부' 카테고리의 다른 글
스프링 기본편 정리 6 (0) | 2023.11.01 |
---|---|
스프링 기본편 정리 5 (0) | 2023.11.01 |
스프링 기본편 정리 4 (0) | 2023.11.01 |
스프링 기본편 정리2 (0) | 2023.11.01 |
스프링 기본편 정리1 (0) | 2023.11.01 |