๐Spring ์ปดํฌ๋ํธ ์ค์บ
ํต์ฌ์๋ฆฌ ์๋ฆฌ์ฆ
์์ ๊ธ ๋ง์ง๋ง์ ๋งํ ๊ฒ ์ฒ๋ผ ์ด๋ฒ์ ์กฐ๊ธ ๋ ์ค์ ์ ์ด๊ณ ์คํ๋ง์ ํธํ๊ฒ ์ธ ์ ์๋ ๋ฐฉ๋ฒ์ ๋ํด ์ ๋ฆฌํด๋ณผ ๊ฒ์ด๋ค.
- ์คํ๋ง์ ์ค์ ์ ๋ณด๊ฐ ์์ด๋ ์๋์ผ๋ก Bean์ ๋ฑ๋กํ๋ ์ปดํฌ๋ํธ ์ค์บ(Component Scan)์ด๋ผ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
- ๋ํ ์์กด๊ด๊ณ๋ ์๋์ผ๋ก ์ฃผ์ ํ๋ @Autowired ๋ผ๋ ๊ธฐ๋ฅ๋ ์ ๊ณตํ๋ค.
์ด์ฌํ AppConfig๋ฅผ ๋ง๋ค๊ณ @Bean์ ๋ถ์ฌ์ ์์ฑํ ๋ค์ getBean()์ ํธ์ถํด์ ์ป์ด์ค๋ ์ฐ์ํ์ง ๋ชปํ(?) ๋ฐฉ์์ ๋ฒ์ด๋, ์คํ๋ง์ด ์๋์ผ๋ก ๋ฌด์ธ๊ฐ๋ฅผ ํด์ฃผ๋ ๊ฒ์ด๋ค. ์ด์ ๋ถํฐ ๊ตฌ์ฒด์ ์ผ๋ก ์์๋ณด์.
@Configuration
@ComponentScan()
public class AutoAppConfig {
}
ํด๋์ค ์์ ๋ด์ฉ์ด ๋ชจ๋ ์ฌ๋ผ์ ธ๋ฒ๋ ธ๋ค. ๋์ ์ปดํฌ๋ํธ ์ค์บ์ด๋ผ๋ ์ ๋ ธํ ์ด์ ์ด ํ๋ ์ถ๊ฐ๋์์ ๋ฟ์ด๋ค. ์ด์ ์ด ๋ ์์ @Component๋ผ๋ ์ ๋ ธํ ์ด์ ์ด ๋ถ์ ํด๋์ค๋ฅผ ๋ชฝ๋ ์ฐพ์์(๋์ค์ ๋๋ฆ ๊ท์น์ด ์๊ธดํ์ง๋ง), Bean์ผ๋ก ๋ฑ๋ก์ํจ๋ค. ์๋์ ๊ฐ์ด.
@Component
public class MemoryMemberRepository implements MemberRepository {}
@Component("RatePolicyBean")
public class RateDiscountPolicy implements DiscountPolicy {}
์ด์ ์์ ๋ค์์ ์ต์ํ ์ด ๋ ์๋ค์ด ์ ๋ ธํ ์ด์ ํ๋์ Bean์ผ๋ก ๋ฑ๋ก์ด ๋์๋ค. ๋๋ฒ์งธ ์ ๋ ธํ ์ด์ ์ฒ๋ผ ์ด๋ฆ์ ์ง์ ํ๋ฉด Bean์ ์ด๋ฆ๋ ์ง์ ํ ์ ์๋ค. ์ด๋ฒ์ ์ด๋ ๊ฒ ๋ฑ๋กํ Bean์ ์ฃผ์ ๋ฐ๋ ๋ฐฉ์๋ ์ดํด๋ณด์.
@Component
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
์ด๋ ๊ฒ ์์ฑ์ ํ๋ฉด MemberServiceImpl ์ญ์ Bean์ด ๋ ๋ฟ๋๋ฌ ์์ฑ์ ์์ @Autowired ์ ๋ ธํ ์ด์ ์ ๋ถ์ฌ์ฃผ๋ฉด ์๋์ผ๋ก ๊ฐ์ฒด๊ฐ ์ฃผ์ ์ด ๋๋ค. ์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋ก๋ ํ ์ด๋ธ์ ๋ค์ ธ์ ๋ง๋ ํ์ ์ Bean ๊ฐ์ฒด๋ฅผ ๋ฃ์ด์ฃผ๋ ๊ฒ์ด๋ค.
์ด์ ๋ฐฉ์๋ค์ ๋นํด ์์ฃผ์์ฃผ ํธ๋ฆฌํ๋ค. ์์ฑ์ ์ธ์๋ ์ฌ๋ฌ ๋ฐฉ๋ฒ์ด ์๋๋ฐ ์ถํ์ ์์๋ณผ ๊ฒ์ด๋ฉฐ ์์ฑ์ ์ฃผ์ ์ด ๊ฐ์ฅ ๊ถ์ฅ๋๋ ๋ฐฉ์์ด๋ค.
88 ํ์ด์ง ๊ทธ๋ฆผ ์ฒจ๋ถ
(๊ทธ๋ฆฌ๊ณ ๋ญ๊ฐ ๊ฐ์กฐ๋ ๋ฐ์ค ์ด๋ฐ๊ฑฐ ์ ์์ฐ๊ณ ์๋๋ฏ. ๋ค์ ๊ฒํ )
@ComponentScan(
basePackages = {"hello.core", "hello.service"}
}
์๊น ๋ชจ๋ ์ปดํฌ๋ํธ๋ฅผ ์ฐพ๋๋ค๋ผ๋ ๋ง์ ํ์๋๋ฐ, ๊ตฌ์ฒด์ ์ผ๋ก๋ ์์์ ์ง์ ํ ๋๋ ํ ๋ฆฌ์ ํ์์์ ๋ชจ๋ @Component๋ฅผ ์ฐพ๋๋ก ๋์ด์๋ค. ์ฒ์์ฒ๋ผ basePackages๋ฅผ ์ง์ ํ์ง ์์ผ๋ฉด @ComponentScan์ ๋ถ์ธ ํด๋์ค์ Package๋ฅผ ๊ธฐ์ค์ผ๋ก ๊ฒ์ํ๋ฉฐ ๋ณดํต ์ด๋ ๊ฒ ์ฌ์ฉํ๋ค๊ณ ํ๋ค. (๊ทธ๋ฌ๊ธฐ ์ํด์๋ ์ค์ ์ ๋ณด ํด๋์ค๋ฅผ ํ๋ก์ ํธ์ ์ต์๋จ์ ๋์ด์ผํ ๊ฒ์ด๋ค)
์ปดํฌ๋ํธ ์ค์บ์ ๋์
@Component
: ์ปดํฌ๋ํธ ์ค์บ์์ ์ฌ์ฉ@Controlller
: ์คํ๋ง MVC ์ปจํธ๋กค๋ฌ์์ ์ฌ์ฉ@Service
: ์คํ๋ง ๋น์ฆ๋์ค ๋ก์ง์์ ์ฌ์ฉ@Repository
: ์คํ๋ง ๋ฐ์ดํฐ ์ ๊ทผ ๊ณ์ธต์์ ์ฌ์ฉ@Configuration
: ์คํ๋ง ์ค์ ์ ๋ณด์์ ์ฌ์ฉ
์ ๋ค์ฏ๊ฐ์ง ์ ๋ ธํ ์ด์ ์ด ๋ถ์ ๋ ์(ํด๋์ค)๋ค์ Bean์ด ๋๋ค๋ ์ด์ผ๊ธฐ์ด๋ค.
@Component
public @interface Controller {
}
IntelliJ ๋ฑ์ ํตํด @Controller ์ ๋ ธํ ์ด์ ์ ๋ฐ๋ผ๊ฐ๋ณด๋ฉด ์ ๋ ธํ ์ด์ ์ ์ ์์ @Component๊ฐ ๋ถ์ด์๋ ๊ฒ์ ์ ์ ์๋ค. ๋ฐ๋ผ์ Bean์ผ๋ก ๋ฑ๋ก๋๋ ๊ฒ์ด๋ค. ๋ค๋ง ์ด๋ฐ ์ ๋ ธํ ์ด์ ์๋ ์์ JAVA์์๋ ์์๊ด๊ณ๋ผ๋๊ฒ ์๋๋ฐ ์คํ๋ง์ ์ํด์ ๊ฐ๋ฅํด์ง ๊ธฐ๋ฅ์ด๋ ๊ฒ์ ์ฃผ์ํ์. ์์ JAVA์์๋ ํ์ค์ผ๋ก ๋ฐ์๋ค์ด๋ฉด ์ข์ ๊ธฐ๋ฅ์ธ ๊ฒ ๊ฐ๋ค.
@ComponentScan(
includeFilters = {
@Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class)
},
excludeFilters = {
@Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class),
@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = BeanA.class)
}
)
์๋์ผ๋ก Bean์ ์ค์บํ๊ธฐ ๋๋ฌธ์ ๋น์ฐํ๊ฒ๋ ๊ฒ์์์ ์ ์ธ๋๋ Bean๋ ์ ์๋ฅผ ํ ์๊ฐ ์์ด์ผ ํ๋ค. ์ ์ฝ๋๋ฅผ ๋ณด๋ฉด ์ฌ์ฉ๋ฒ์ ์ด๋ ต์ง ์๊ฒ ์ง๋ง ๋ง์ด ์ฌ์ฉ๋์ง๋ ์๋๋ค๊ณ ํ๋ค. ํนํ๋ IncludeFilter์ ๊ฒฝ์ฐ๋ ๋์ฑ ๋.
๋ง์ฝ ์๋ ์ปดํฌ๋ํธ ์ค์บ ์ค์ ์ด๋ฆ ํน์ ํ์ ์ด ๋์ผํ Bean์ด ์กด์ฌํ์ฌ ์ถฉ๋์ด ์ผ์ด๋๋ฉด ์ด๋ป๊ฒ ๋ ๊น? ์ต๊ทผ์ ์์ ๊ธฐ์ค์ผ๋ก ์ด์ผ๊ธฐํ์๋ฉด ์คํ๋ง์ด ์ถฉ๋์ ์๋ฌ๋ฅผ ๋ฐ์์์ผ ๊ฐ๋ฐ์๊ฐ ์ถฉ๋์ ์ ์ ์๋๋ก ํ์๋ค. ์ผ๋จ์ ๊ฑฑ์ ํ ํ์๊ฐ ์๋ ๊ฒ์ด๋ค.
์ด์ ์ปดํฌ๋ํธ ์ค์บ์ ํตํด Bean์ ์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋ก์์ผฐ์ผ๋, Bean์ ์ฝ๊ฒ ์ฃผ์ ๋ฐ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์ธํ ์์๋ณด์.
์์กด๊ด๊ณ ์๋ ์ฃผ์
์์กด๊ด๊ณ ์๋ ์ฃผ์ ์ ๋ฐฉ๋ฒ์๋ ์๋ ๋ค ๊ฐ์ง๊ฐ ์๋ค.
- ์์ฑ์ ์ฃผ์
- Setter ์ฃผ์
- ํ๋ ์ฃผ์
- ์ผ๋ฐ ๋ฉ์๋ ์ฃผ์
๋จผ์ ์์ ์ ๊น ์๊ฐํ๊ณ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ธ ์์ฑ์ ์ฃผ์ ๋ฐฉ์์ ์๋์ ๊ฐ์ด ์ฌ์ฉํ๋ค. ์์ฑ์ ์ฃผ์ ์ ๊ฒฝ์ฐ ์ฒ์ Bean์ด ์ธํ ๋๋ฉด ๋ถ๋ณ์ด๋ค. ์ ๋ต ํจํด๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค๋ ์๋ฏธ์ด์ง๋ง ์ด๋ฐ ์ ์ฆ์ผ์ด์ค๋ ๋ง์ด ์์ผ๋ฏ๋ก ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ ๋ฐฉ์์ด๋ค.
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ ๋ฐฉ์๋ต๊ฒ ์์ฑ์๊ฐ ํ๋๋ง ์๋ ๊ฒฝ์ฐ์๋ @Autowired๋ฅผ ์๋ตํ์ฌ๋ ์์ฑ์ ์ฃผ์ ์ด ์ด๋ฃจ์ด์ง๋ค. ๊ฐ์ธ์ ์ผ๋ก๋ ๋ฌด์กฐ๊ฑด ๊ฐ๋ฅํ ๋ช ์์ ์ธ๊ฒ ์ข์ง์๋ ํ๋ ์๊ฐ์ ๋ถ์ด๋๊ฑธ ์ ํธํ๋ค.
๋ค์์ Setter ์ฃผ์ ์ด๋ค. ๋์ ์ผ๋ก ๋ณ๊ฒฝ๋๋ ๊ฒฝ์ฐ์๋ ์ฌ์ฉํ ์ ์์ง๋ง ์ฌ์ฉ๋น๋๋ ๋์ง ์๋ค๊ณ ํ๋ค.
private MemberRepository memberRepository;
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
โQuestionโ
์ ๋ต ํจํด์ฒ๋ผ ๋์ ์ผ๋ก ๋ค๋ฅธ Bean์ ์ฃผ์ ํ๋ฉด ์ ์ฉํ์ง ์์๊น? ํ์ง๋ง Bean์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฑ๊ธํด์ด๊ธฐ ๋๋ฌธ์ Statelessํ๋ค๋๊ฑธ ์๊ฐํด๋ณด๋ฉด ์ผ๋ง๋ ์ ์ฉํ ๊น ์ถ๊ธด ํ๋ค. ๋ค์์ ์๊ฐํ ์ฑ๊ธํด์ด ์๋ ํ๋กํ ํ์ Bean๊ณผ์ ์์ฉ์ ๋ํด์๋ ์ฐ๊ตฌํด๋ณผ ๊ฐ์น๊ฐ ์์ ๊ฒ ๊ฐ๋ค.
๋ค์์ ๊ฐ๊ฒฐํ์ ๋ํ์์ธ ํ๋ ์ฃผ์ ์ด๋ค. ๊ฒฐ๋ก ๋ถํฐ ๋งํ์๋ฉด ์ฌ์ฉํ์ง ๋ง์. ๋ค์ Lombok ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํด ์ค๋ช ํ ๊ฒ์ด๋ค. ํด๋น ๊ธฐ๋ฅ์ ํ์ฉํ๋ค๋ฉด ์ข๋ค.
@Component
public class OrderServiceImpl implements OrderService {
@Autowired
private MemberRepository memberRepository; // ๋!
ํ๋ ์ฃผ์ ์ ์ธ๋ถ์์ ๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅํ๊ณ ๋ฐ๋ผ์ ํ ์คํธ๋ ์ฝ์ง ์๋ค. ๊ทธ๋ฆฌ๊ณ ๋๋ฌด๋๋ ๋ช ์์ ์ด์ง ์์ผ๋ฉฐ, DI ํ๋ ์์ํฌ๊ฐ ์๋ค๋ฉด null reference exception์ ๋ง์ฃผํ๊ฒ ๋ ๊ฒ์ด๋ค. Lombok์ด ์์ผ๋ฉด ๋ชจ๋ฅด๊ฒ ๋๋ฐ ์์ผ๋ ๋จ๋ ์ผ๋ก๋ ์ฌ์ฉํ์ง ๋ง ๊ฒ!
๋ง์ง๋ง์ผ๋ก ์ผ๋ฐ์ ์ธ ๋ฉ์๋์์๋ ์ฃผ์ ์ด ๊ฐ๋ฅํ๋ค. ์ฌ์ค์ ์ํ๋ค๋ฉด ์ด๋ค ํํ๋ก๋ ๋ฐ์ ์ ์๋ ๊ฒ์ด๋ค. ํ์ง๋ง ์ด ์ญ์ ๋น์ถ์ฒ์ด๋ค.
@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
โ@Autowired์ ์ต์ โ
์ ์ด์ ์ด๋ฐ ์ต์ ์ด ์ฐ์ด์ง ์๋๊ฒ ์ข์ ์ ์์ง๋ง ๋ฐฉ์ด์ ์ธ ์ฐจ์์์ ์์๋์. Optional์ KOTLIN์ null ์ฒ๋ฆฌ์ฒ๋ผ ์ธ ์ ์๋ JAVA ๋ฌธ๋ฒ์ด์ง๋ง ๋ ๊ฐ๋จํ ๋ฌธ๋ฒ์ ์ํ๋ค! ์๋ฐ์๊ฒ!
//ํธ์ถ ์๋จ
@Autowired(required = false)
public void setNoBean1(Member member) {
System.out.println("setNoBean1 = " + member);
}
//null ํธ์ถ
@Autowired
public void setNoBean2(@Nullable Member member) {
System.out.println("setNoBean2 = " + member);
}
//Optional.empty ํธ์ถ
@Autowired(required = false)
public void setNoBean3(Optional<Member> member) {
System.out.println("setNoBean3 = " + member);
}
์์ฑ์ ์ฃผ์ ์ ์ฌ์ฉํด์ Bean์ ์ฃผ์ ๋ฐ์ ์ ์๋ ๊ฒฝ์ฐ์๋ ์ปดํ์ผ๋ฌ๋ฅผ ํตํด์ ํต์ง๋ฅผ ๋ฐ๋ํธ์ด ๊ฐ์ฅ ์์ ํ๊ธฐ ๋๋ฌธ์ ์์ฑ์ ์ฃผ์ ์ด ๊ฐ์ฅ ๋ง์ด ์ฐ์ด๋ ๊ฒ ๊ฐ๋ค. ์ปดํ์ผ(์)๋ฌ ์งฑ! ๊ทธ๋ฆฌ๊ณ ๋ ์์ ํ ์ฒ๋ฆฌ๋ฅผ ์ํ์ฌ final ํค์๋๋ฅผ ๊ฐ๋ฏธํด๋ณผ ์ ์๋ค. (์์ฑ์ ์ฃผ์ ๋ฐฉ์์ ๋ถ๋ณ์๋ง ์ฌ์ฉํ๋ฏ๋ก)
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
}
์ด๋ฌํ ํน์ฑ ๋๋ฌธ์ ์์ฑ์ ์ฃผ์ ์ ๊ฐ์ฅ JAVA ๋ณธ์ฐ์ ๊ธฐ๋ฅ์ ์ ์ด๋ฆฐ๋ค ํ ์ ์๋ค. ์์ฑ์ ์ฃผ์ ์ด ๊ถ์ฅ๋๋ ์ด์ ๋ผ๊ณ ํ ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ ์ฌ๊ธฐ์ ์ฐฐ๋ก์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๊น๋ ์ ๊น ์ธ๊ธํ๋ Lombok์ด๋ค. ์ด๋ป๊ฒ ํธ๋ฆฌํด์ง๋์ง ์ฝ๋๋ก ๋ฐ๋ก ์ดํด๋ณด์.
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
}
@RequiredArgsConstructor์ ์ํด ์์ฑ์๊ฐ ์๋์ผ๋ก ์์ฑ๋๋ค. ์ ๋ ธํ ์ด์ ์ ์ํ ๋ฉํ ํ๋ก๊ทธ๋๋ฐ์ด๋ผ ํ ์ ์๋ค. ์ด์ ๊ฐ์ฅ ๊ฐ๋จํ ํ๋ ์ฃผ์ ์ ํํ๋ก ๊ฐ์ฅ ์์ ํ ์์ฑ์ ์ฃผ์ ๋ฐฉ์์ ๊ตฌํํ ์ ์๊ฒ ๋์๋ค. ์ด-์ง.
โBean ์๋ ๋ฑ๋ก์ด ํ์ํ ๊ฒฝ์ฐโ
๋จผ์ ํผ๋ํ์ง ๋ง์. ์๋ ๋ฑ๋ก์ ์์ AppConfig ์์์ @Bean ์ ๋ ธํ ์ด์ ์ ํตํด ๋ฑ๋กํ๋ ๋ฐฉ์์ด๋ค. ๊ทธ๋ ๋ค๋ฉด ์ด๋ ๊ฒ ํธํ ์๋์์คํ ์ด ์๋๋ฐ ์๋์ ์ด๋ค ๊ฒฝ์ฐ์ ํ์ํ ๊น? AOP๋ฅผ ํ์ฉํ ๊ธฐ์ ์ง์ ํด๋์ค์ ๊ฒฝ์ฐ ์๋๋ฑ๋กํ์ฌ ์ฝ๊ฒ ์ฝ๋ ๊ตฌํ๋ถ๋ฅผ ์ ๊ทผํ๋ฉด ์ข๋ค. ๋ชจ๋ ์ฝ๋์ ์๋จ ๋ท๋จ์์ ์ ์ฉ๋๋ ๊ฐ๋ ์ด๊ธฐ ๋๋ฌธ์ ๊ทธ๋ ๋ค.
์๋ ์ฃผ์ ์ ์ถฉ๋ ๋ฌธ์
์๋์ ๊ฐ์ Bean์ด ์๋์ฃผ์ ๋๋ฉด ์ด๋ค์ผ์ด ๋ฒ์ด์ง๊น?
@Component
public class FixDiscountPolicy implements DiscountPolicy {}
@Component
public class RateDiscountPolicy implements DiscountPolicy {}
@Autowired
private DiscountPolicy discountPolicy;
์ปดํ์ผ๋ฌ๊ฐ ์น์ ํ๊ฒ๋ ์ค๋ฅ๋ฅผ ๋ฐ์์์ผ์ค๋ค. ๋คํ์ด๋ค. ๊ทธ๋ ๋ค๋ฉด ์ด๋ฐ ์ถฉ๋์ ์ด๋ป๊ฒ ํด๊ฒฐํ ๊น? ์ฌ๋ฌ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค. ํ๋ํ๋์ฉ ์ดํด๋ณด๋๋ก ํ์.
๋จผ์ ํ๋ ๋ช ์ Bean ์ด๋ฆ์ผ๋ก ๋ณ๊ฒฝํ๋ ๋ฐฉ๋ฒ์ด ์๋ค. ์โฆ๊ทนํ์ด๋ค(?) ๋ฌธ๋ฒ๋ง์ผ๋ก ์์๋ผ ์ ์๋ ์ด๋ฐ ๋งค์ง์ ์ ๋ง์ด์ง ์ซ๋ค. ๊ทผ๋ฐ ์๋ฌดํผ ๋๋ค.
@Autowired
private DiscountPolicy rateDiscountPolicy
๋ค์์ @qualifier๋ฅผ ํ์ฉํด ๋ช ์์ ์ด๋ฆ์ ์ง์ ํ๋ ๋ฐฉ์์ด๋ค. ์์ฑ๊ณผ ์ฌ์ฉ์ ์ด๋ฆ์ ๋ถ์ฌ์ ์ง์ ๋ง์ถ๋ค.
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {}
@Autowired
public DiscountPolicy setDiscountPolicy(@Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
return discountPolicy;
}
๋ค์์ @Primary ์ ๋ ธํ ์ด์ ์ ํ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค. ๋์์ ๊ฐ๋จํ๋ค. @Primary ์ ๋ ธํ ์ด์ ์ด ๋ถ์ Bean์ด ์ฐ์ ์ ์ผ๋ก ์ ํ๋๋ค.
@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
public class FixDiscountPolicy implements DiscountPolicy {}
@Primary์ @Qualifier๊ฐ ํจ๊ป ์ฐ์ด๋ฉด ์ด๋ป๊ฒ ๋ ๊น? ํญ์ ๊ทธ๋ ๋ฏ ๋ช ์์ ์ธ ๊ฒ์ด ์๋๋ณด๋ค ์ฐ์ ๊ถ์ ๊ฐ์ง๋ค. @Qualifier๊ฐ ์ฐ์ ์ ์ผ๋ก ์ฐ์ธ๋ค. ์ด๋ฐ ์ฌํญ์ ์ ์ฆ์ผ์ด์ค๊ฐ ์๋๋ฐ, ๋ฉ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํ Connector์ ํ ์คํธ์ฉ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํ Connector๊ฐ ์์ ๋ ๋ฉ์ธ์ @Primary, ์๋ธ์ ํ์์ @Qualifier๋ฅผ ์ฌ์ฉํ๋ฉด ๊น๋ํ๊ฒ ์ฒ๋ฆฌํ ์ ์๋ค.
Bean์ ํ์ฉํ ์ ๋ตํจํด ๊ตฌํ
์๋ ํ ์คํธ ํจ์๋ฅผ ์ ๋ตํจํด์ ํตํด ๊ตฌํํด๋ณด์. discount ํจ์์ ๊ฒฐ๊ณผ๊ฐ Policy์ ์ํด ๊ฒฐ์ ๋ ๊ฒ์ด๋ค.
@Test
void findAllBean() {
ApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class, DiscountService.class);
DiscountService discountService = ac.getBean(DiscountService.class);
Member member = new Member(1L, "userA", Grade.VIP);
int discountPrice = discountService.discount(member, 10000, "fixDiscountPolicy");
assertThat(discountPrice).isEqualTo(1000);
}
๊ทธ๋ฆฌ๊ณ ์๋ ์ฝ๋์์ Map๊ณผ List๋ฅผ ํตํด Bean์ ๋ค๋ฐ๋ก ์ ๋ฌ๋ฐ์์ ์ ๋ตํจํด์ ๊ตฌํํ๋ค.
โRemindโ
ํ์ ์ผ๋ก Bean์ ์ป์ด์ค๋ฉด ๋งค์น๋๋ ๋ชจ๋ Bean์ ๊ฐ์ ธ์จ๋ค๋ ๊ฒ์ ์๊ธฐํ์!
์ด์ ์๋ ์ฝ๋์์ ์์ฑ์ ์ฃผ์ ๋ถ๋ถ์ ์ง์คํด์ ์ดํด๋ณด์.
static class DiscountService {
private final Map<String, DiscountPolicy> policyMap;
private final List<DiscountPolicy> policies;
public DiscountService(Map<String, DiscountPolicy> policyMap, List<DiscountPolicy> policies) {
this.policyMap = policyMap;
this.policies = policies;
System.out.println("policyMap = " + policyMap);
System.out.println("policies = " + policies);
}
public int discount(Member member, int price, String discountCode) {
DiscountPolicy discountPolicy = policyMap.get(discountCode);
System.out.println("discountCode = " + discountCode);
System.out.println("discountPolicy = " + discountPolicy);
return discountPolicy.discount(member, price);
}
}
โQuestionโ
์ ๋ ๊ฒ String์ผ๋ก ์ ๋ต์ ์ป์ด์์ ์คํํ๋๊ฑธ ์ ๋ตํจํด์ด๋ผ๊ณ ํ ์ ์์๊น? ๋ ๊ฐ์ฒด์งํฅ์ค๋ฌ์ด ๋ฐฉ๋ฒ์ด ์์์ง ๋ชจ๋ฅธ๋ค. ์ฐ๊ตฌํด๋ณด์.
์ค๋ฌด์ ์ผ๋ก ์ค์ํ ์ปดํฌ๋ํธ ์ค์บ๊ณผ Bean ์๋์ฃผ์ ์ ๋ํด ์ดํด๋ณด์๋ค. ์ ๋ฒ ๋ถ๋์ด ๋ง์๋ค. ์ด์ ๋ถํฐ๋ ์๋์ ์ผ๋ก ๋ ์ค์ํ ๋ถ๋ถ๋ค์ ์ ๋ฆฌํ๊ณ ์คํ๋ง ๊ธฐ๋ณธ์๋ฆฌ์ ๋ํ ์ ๋ฆฌ๋ฅผ ๋ง๋ฌด๋ฆฌํด๋ณด๋๋ก ํ์!