@Configuration๊ณผ ์ฑ๊ธํค
AppConfig ์ฝ๋
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
memberRepository ํธ์ถ ์ new MemoryMemberRepositroy() ํธ์ถ
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
memberService ๋น์ ๋ง๋๋ ์ฝ๋๋ฅผ ๋ณด๋ฉด memberRepository() ๋ฅผ ํธ์ถํ๋ค.
์ด ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด new MemoryMemberRepository() ๋ฅผ ํธ์ถํ๋ค.
@Bean
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
orderService ๋น์ ๋ง๋๋ ์ฝ๋๋ ๋์ผํ๊ฒ memberRepository() ๋ฅผ ํธ์ถํ๋ค.
์ด ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด new MemoryMemberRepository() ๋ฅผ ํธ์ถํ๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก ๊ฐ๊ฐ ๋ค๋ฅธ 2๊ฐ์ MemoryMemberRepository ๊ฐ ์์ฑ๋๋ฉด์ ์ฑ๊ธํค์ด ๊นจ์ง๋ ๊ฒ ์ฒ๋ผ ๋ณด์ธ๋ค.
์คํ๋ง ์ปจํ ์ด๋๋ ์ด ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ ๊น?
๊ฒ์ฆ ์ฉ๋์ ์ฝ๋ ์ถ๊ฐ
//ํ
์คํธ ์ฉ๋
public MemberRepository getMemberRepository() {
return memberRepository;
}
memberService ์์์ memberRepository ๋ฐํํ๋ ๋ฉ์๋ ์ถ๊ฐ
//ํ
์คํธ ์ฉ๋
public MemberRepository getMemberRepository() {
return memberRepository;
}
orderService ์์์ memberRepository ๋ฐํํ๋ ๋ฉ์๋ ์ถ๊ฐ
@Test
void configurationTest() {
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
AppConfig ์ค์ ํ์ผ์ ๊ตฌ์ฑ์ ๋ณด๋ก ์ฌ์ฉํ๋ ์ปจํ ์ด๋ ์์ฑ
MemberServiceImpl memberService = ac.getBean("memberService",MemberServiceImpl.class);
MemberRepository memberRepository1 = memberService.getMemberRepository();
MemberServiceImpl ํ์ ์ ๋น์ ๋ฐํ
์คํ๋ง์ด ์ปจํ ์ด๋์์ ์ฒ์์ ๋ฑ๋กํ ๋น์ ๋ฐํ
memberServiceImpl ๊ฐ์ฒด์์์ memberRepository ๋ฅผ ๋ฐํ
OrderServiceImpl orderService = ac.getBean("orderService",OrderServiceImpl.class);
MemberRepository memberRepository2 = orderService.getMemberRepository();
OrderServiceImpl ํ์ ์ ๋น์ ๋ฐํ
์คํ๋ง์ด ์ปจํ ์ด๋์์ ์ฒ์์ ๋ฑ๋กํ ๋น์ ๋ฐํ
orderServiceImpl ๊ฐ์ฒด์์์ memberRepository ๋ฅผ ๋ฐํ
System.out.println("memberSerivce -> memberRepository1 = " + memberRepository1);
System.out.println("orderService -> memberRepository2 = " + memberRepository2);
๊ฐ๊ฐ์ ๊ฐ์ฒด์์ ํ์ธํ memberRepository ๋น๊ต
MemberRepository memberRepository = ac.getBean("memberRepository", MemberRepository.class);
MemberRepository ํ์ ์ ๋น์ ๋ฐํ
์คํ๋ง์ด ์ปจํ ์ด๋์์ ์ฒ์์ ๋ฑ๋กํ ๋น์ ๋ฐํ
Assertions.assertThat(memberService.getMemberRepository()).isSameAs(memberRepository);
Assertions.assertThat(orderService.getMemberRepository()).isSameAs(memberRepository);
๊ฐ์ ์ธ์คํด์ค์ธ์ง ๊ฒ์ฆ
ํ์ธํด๋ณด๋ฉด memberRepository ์ธ์คํด์ค๋ ๋ชจ๋ ๊ฐ์ ์ธ์คํด์ค๊ฐ ๊ณต์ ๋์ด ์ฌ์ฉ๋๋ค.
AppConfig์ ์๋ฐ ์ฝ๋๋ฅผ ๋ณด๋ฉด ๋ถ๋ช ํ ๊ฐ๊ฐ 2๋ฒ new MemoryMemberRepository ํธ์ถํด์
๋ค๋ฅธ ์ธ์คํด์ค๊ฐ ์์ฑ๋์ด์ผ ํ๋๋ฐ?
์ด๋ป๊ฒ ๋ ์ผ์ผ๊น? ํน์ ๋ ๋ฒ ํธ์ถ์ด ์๋๋ ๊ฒ์ผ๊น? ์คํ์ ํตํด ์์๋ณด์.
AppConfig์ ํธ์ถ ๋ก๊ทธ ๋จ๊ฒจ๋ณด์
@Configuration
public class AppConfig {
@Bean
public MemberRepository memberRepository() {
System.out.println("call AppConfig.memberRepository");
return new MemoryMemberRepository();
}
@Bean
public MemberService memberService() {
System.out.println("call AppConfig.memberService");
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService() {
System.out.println("call AppConfig.orderService");
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
์์)
์คํ๋ง ์ปจํ ์ด๋๊ฐ ๊ฐ๊ฐ @Bean์ ํธ์ถํด์ ์คํ๋ง ๋น์ ์์ฑํ๋ค.
๊ทธ๋์ memberRepository() ๋ ๋ค์๊ณผ ๊ฐ์ด ์ด 3๋ฒ์ด ํธ์ถ๋์ด์ผ ํ๋ ๊ฒ ์๋๊น?
1. ์คํ๋ง ์ปจํ ์ด๋๊ฐ ์คํ๋ง ๋น์ ๋ฑ๋กํ๊ธฐ ์ํด @Bean์ด ๋ถ์ด์๋ memberRepository() ํธ์ถ
memberRepository() ํธ์ถ
"call AppConfig.memberRepository"
2. memberService() ๋ก์ง์์ memberRepository() ํธ์ถ
memberService() ํธ์ถ
"call AppConfig.memberSerivce"
memberRepository() ํธ์ถ
"call AppConfig.memberRepository"
3. orderService() ๋ก์ง์์ memberRepository() ํธ์ถ
orderSerivce() ํธ์ถ
"call AppConfig.orderSerivce"
memberRepository() ํธ์ถ
"call AppConfig.memberRepository"
์ถ๋ ฅ ๊ฒฐ๊ณผ
๋ฐ์ดํธ์ฝ๋ ์กฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
์คํ๋ง์ด ์๋ฐ ์ฝ๋๊น์ง ์ด๋ป๊ฒ ํ๊ธฐ๋ ์ด๋ ต๋ค. ์ ์๋ฐ ์ฝ๋๋ฅผ ๋ณด๋ฉด ๋ถ๋ช 3๋ฒ ํธ์ถ๋์ด์ผ ํ๋ ๊ฒ์ด ๋ง๋ค.
๊ทธ๋์ ์คํ๋ง์ ํด๋์ค์ ๋ฐ์ดํธ์ฝ๋๋ฅผ ์กฐ์ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค.
๋ชจ๋ ๋น๋ฐ์ @Configuration ์ ์ ์ฉํ AppConfig ์ ์๋ค.
@Test
void configurationDeep() {
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
์ปจํ ์ด๋ ์์ฑ
AppConfig bean = ac.getBean(AppConfig.class);
System.out.println("bean = " + bean.getClass());
AnnotationConfigApplicationContext ์ ํ๋ผ๋ฏธํฐ๋ก ๋๊ธด ๊ฐ์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก๋๋ค.
๊ทธ๋์ AppConfig ๋ ์คํ๋ง ๋น์ด ๋๋ค.
AppConfig ์คํ๋ง ๋น์ ์กฐํํด์ ํด๋์ค ์ ๋ณด๋ฅผ ์ถ๋ ฅํด๋ณด์.
์์ํ ํด๋์ค๋ผ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ถ๋ ฅ๋์ด์ผ ํ๋ค.
class hello.core.AppConfig
๊ทธ๋ฐ๋ฐ ์์๊ณผ๋ ๋ค๋ฅด๊ฒ ํด๋์ค ๋ช ์ xxxCGLIB๊ฐ ๋ถ์ผ๋ฉด์ ์๋นํ ๋ณต์กํด์ง ๊ฒ์ ๋ณผ ์ ์๋ค.
์ด๊ฒ์ ๋ด๊ฐ ๋ง๋ ํด๋์ค๊ฐ ์๋๋ผ ์คํ๋ง์ด CGLIB๋ผ๋ ๋ฐ์ดํธ์ฝ๋ ์กฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด์
AppConfig ํด๋์ค๋ฅผ ์์๋ฐ์ ์์์ ๋ค๋ฅธ ํด๋์ค๋ฅผ ๋ง๋ค๊ณ , ๊ทธ ๋ค๋ฅธ ํด๋์ค๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ ๊ฒ์ด๋ค!
๊ทธ ์์์ ๋ค๋ฅธ ํด๋์ค๊ฐ ๋ฐ๋ก ์ฑ๊ธํค์ด ๋ณด์ฅ๋๋๋ก ํด์ค๋ค.
AppConfig@CGLIB ์์ ์ฝ๋
@Bean
public MemberRepository memberRepository() {
if (memoryMemberRepository๊ฐ ์ด๋ฏธ ์คํ๋ง ์ปจํ
์ด๋์ ๋ฑ๋ก๋์ด ์์ผ๋ฉด?) { return ์คํ๋ง ์ปจํ
์ด๋์์ ์ฐพ์์ ๋ฐํ;
} else { //์คํ๋ง ์ปจํ
์ด๋์ ์์ผ๋ฉด
๊ธฐ์กด ๋ก์ง์ ํธ์ถํด์ MemoryMemberRepository๋ฅผ ์์ฑํ๊ณ ์คํ๋ง ์ปจํ
์ด๋์ ๋ฑ๋ก return ๋ฐํ
} }
@Bean์ด ๋ถ์ ๋ฉ์๋๋ง๋ค ์ด๋ฏธ ์คํ๋ง ๋น์ด ์กด์ฌํ๋ฉด ์กด์ฌํ๋ ๋น์ ๋ฐํํ๊ณ ,
์คํ๋ง ๋น์ด ์์ผ๋ฉด ์์ฑํด์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๊ณ ๋ฐํํ๋ ์ฝ๋๊ฐ ๋์ ์ผ๋ก ๋ง๋ค์ด์ง๋ค.
@Configuration ์ ์ ์ฉํ์ง ์๊ณ , @Bean ๋ง ์ ์ฉํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
//@Configuration ์ญ์
public class AppConfig {
์ด ์ถ๋ ฅ ๊ฒฐ๊ณผ๋ฅผ ํตํด์ AppConfig๊ฐ CGLIB ๊ธฐ์ ์์ด ์์ํ AppConfig๋ก ์คํ๋ง ๋น์ ๋ฑ๋ก๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ด ์ถ๋ ฅ ๊ฒฐ๊ณผ๋ฅผ ํตํด์ MemberRepository๊ฐ ์ด 3๋ฒ ํธ์ถ๋ ๊ฒ์ ์ ์ ์๋ค.
1๋ฒ์ @Bean์ ์ํด ์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋กํ๊ธฐ ์ํด์์ด๊ณ , 2๋ฒ์ ๊ฐ๊ฐ memberRepository() ๋ฅผ ํธ์ถํ๋ฉด์ ๋ฐ์ํ ์ฝ๋๋ค.
์ธ์คํด์ค๊ฐ ๊ฐ์์ง ํ ์คํธ ๊ฒฐ๊ณผ
System.out.println("memberSerivce -> memberRepository1 = " + memberRepository1);
System.out.println("orderService -> memberRepository2 = " + memberRepository2);
System.out.println("memberRepository = " + memberRepository);
๋น์ฐํ ์ธ์คํด์ค๊ฐ ๊ฐ์์ง ํ ์คํธ ํ๋ ์ฝ๋๋ ์คํจํ๊ณ ,
๊ฐ๊ฐ ๋ค ๋ค๋ฅธ MemoryMemberRepository ์ธ์คํด์ค๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
์ ๋ฆฌ
@Bean๋ง ์ฌ์ฉํด๋ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก๋์ง๋ง, ์ฑ๊ธํค์ ๋ณด์ฅํ์ง ์๋๋ค.
memberRepository() ์ฒ๋ผ ์์กด๊ด๊ณ ์ฃผ์
์ด ํ์ํด์ ๋ฉ์๋๋ฅผ ์ง์ ํธ์ถํ ๋ ์ฑ๊ธํค์ ๋ณด์ฅํ์ง ์๋๋ค.
ํฌ๊ฒ ๊ณ ๋ฏผํ ๊ฒ์ด ์๋ค. ์คํ๋ง ์ค์ ์ ๋ณด๋ ํญ์ @Configuration ์ ์ฌ์ฉํ์.