์์ ์คํ๋ง ๋น์ ๋ฑ๋กํ ๋ @Bean ์ ๋
ธํ
์ด์
์ ๋ถ์ฌ ์ค์ ์ ๋ณด์ ์ง์ ๋ฑ๋กํ ์คํ๋ง ๋น์ ๋์ดํ๋ค.
๊ทธ๋ฐ๋ฐ ํฐ ํ๋ก์ ํธ์์๋ ๋ฑ๋กํด์ผ ํ ๋น์ด ์์ญ, ์๋ฐฑ๊ฐ๊ฐ ๋ ์ ๋ ์๋ค. ๋๋ฝํ ์๋ ์๋ค...๐ฑ
๊ทธ๋์ ์คํ๋ง์ ์ค์ ์ ๋ณด๊ฐ ์์ด๋ ์๋์ผ๋ก ์คํ๋ง ๋น์ ๋ฑ๋กํ๋ ์ปดํฌ๋ํธ ์ค์บ์ด๋ผ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
๋ ์์กด๊ด๊ณ๋ฅผ ์๋์ผ๋ก ์ฃผ์
ํ๋ @Autowired๋ผ๋ ๊ธฐ๋ฅ๋ ์ ๊ณตํ๋ค
๋ค์์ฝ๋๋ฅผ ๋ณด์!
package hello.core;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
@Configuration
@ComponentScan(
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class)
)
public class AutoAppConfig {
}
์ปดํฌ๋ํธ ์ค์บ์ ์ฌ์ฉํ๊ธฐ ์ํด์ @ComponentScan์ ์ค์ ์ ๋ณด์ ๋ถ์ฌ์ฃผ๋ฉด ๋๋ค.
๊ธฐ์กด์ AppConfig์ ๋ค๋ฅด๊ฒ @Bean์ผ๋ก ๋ฑ๋กํ ํด๋์ค๊ฐ ์๋ค...!
์ปดํฌ๋ํธ ์ค์บ์ ์ฌ์ฉํ๋ฉด @Configuration์ด ๋ถ์ ์ค์ ์ ๋ณด๋ ์๋์ผ๋ก ๋ฑ๋ก๋๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ํด๋์ค(AppConfig...)์์ @Configuration์ด ๋ถ์ด ์๊ธฐ ๋๋ฌธ์ excludeFilters๋ฅผ ํตํด ์ ์ธํ๋ค.
๐์ปดํฌ๋ํธ ์ค์บ์ @Component์ ๋
ธํ
์ด์
์ด ๋ถ์ ํด๋์ค๋ฅผ ์ค์บํด์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ค.โ๏ธ
๊ฐ ํด๋์ค๊ฐ ์ปดํฌ๋ํธ ์ค์บ์ ๋์์ด ๋๋๋ก @Component๋ฅผ ๋ถ์๋ค.
@Component
public class MemoryMemberRepository implements MemberRepository {}
@Component
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
@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๋ฅผ ์ฌ์ฉํ ์ด์ ๋ ์ด์ ์ AppConfig์์๋ ์์กด๊ด๊ณ๋ ์ง์ ๋ช ์ํ์ง๋ง ์ปดํฌ๋ํธ ์ค์บ์ผ๋ก ๋ฐ๊พธ๋ฉด์ ์ค์ ์ ๋ณด๊ฐ ์๊ธฐ ๋๋ฌธ์ ์์กด๊ด๊ณ ์ฃผ์ ๋ ๊ฐ ํด๋์ค ์์์ ํด๊ฒฐํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์์กด๊ด๊ณ๊ฐ ํ์ํ ๊ณณ์์๋ ์ฌ์ฉํ๋ค.
package hello.core.scan;
import hello.core.AutoAppConfig;
import hello.core.member.MemberService;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AutoAppConfigTest {
@Test
void basicScan(){
ApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class);
MemberService memberService = ac.getBean(MemberService.class);
Assertions.assertThat(memberService).isInstanceOf(MemberService.class);
}
}
11:00:09.472 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [/Users/leesangjun/Desktop/์คํ๋ง/core/out/production/classes/hello/core/discount/RateDiscountPolicy.class]
11:00:09.473 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [/Users/leesangjun/Desktop/์คํ๋ง/core/out/production/classes/hello/core/member/MemberServiceImpl.class]
11:00:09.474 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [/Users/leesangjun/Desktop/์คํ๋ง/core/out/production/classes/hello/core/member/MemoryMemberRepository.class]
11:00:09.475 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [/Users/leesangjun/Desktop/์คํ๋ง/core/out/production/classes/hello/core/order/OrderServiceImpl.class]
โฌ๏ธ ์์ AutoAppConfigTest์ ๋ก๊ทธ๋ฅผ ๋ณด๋ฉด ์ค์บ์ด ์ ์์ ์ผ๋ก ๋์ํ ๊ฒ์ ๋ณผ์ ์๋ค.๐ฒ๐๐ป๐๐ป
๊ทธ๋ฆผ์ ํตํด ๋์ ๊ณผ์ ์ ์์๋ณด์!
๋ชจ๋ ์๋ฐ ํด๋์ค๋ฅผ ๋ค ์ค์บํ๋ฉด ์๊ฐ์ด ์ค๋๊ฑธ๋ฆฌ๊ธฐ ๋๋ฌธ์ ํ์ํ ์์น๋ถํฐ ์ง์ ํ์ฌ ํ์ํ ์ ์๋ค.
์๋ฅผ๋ค์ด ํ๋ก์ ํธ ๊ตฌ์กฐ๊ฐ ๋ค์๊ณผ ๊ฐ๋ค๋ฉด
com.hello๊ฐ ํ๋ก์ ํธ ์์ ๋ฃจํธ์ด๊ธฐ ๋๋ฌธ์ ๋ณดํต AppConfig๊ฐ์ ๋ฉ์ธ ์ค์ ์ ๋ณด๋ฅผ ๋๊ณ , @ComponentScan์ ๋ ธํ ์ด์ ์ ๋ถ์ธ๋ค.
์ด๋ ๊ฒ ํ๋ฉด com.hello๋ฅผ ํฌํจํ ํ์ ํจํค์ง๋ค์ ๋ชจ๋ ์๋์ผ๋ก ์ปดํฌ๋ํธ ์ค์บ์ ๋์์ด ๋๋ค ๋ณดํต์ ์ด๋ฐ ๋ฃฐ์ ๋ฐ๋ฅธ๋ค.
์ปดํฌ๋ํธ ์ค์บ์์ ๊ฐ์ ๋น ์ด๋ฆ์ ๋ฑ๋กํ๋ฉด ์ถฉ๋์ด ๋ฐ์ํ๋ค.
์์์ ๋ณด์๋ฏ ์ปดํฌ๋ํธ ์ค์บ์ผ๋ก ์๋์ผ๋ก ์คํ๋ง ๋น์ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ์ด ์๊ณ ์๋์ผ๋ก ์คํ๋ง ๋น์ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
์ถฉ๋์ 2๊ฐ์ง ๊ฒฝ์ฐ๋ก ๋ ์ ์๋ค. ์๋ ๋น ๋ฑ๋ก๊ณผ ์๋ ๋น ๋ฑ๋ก
๊ทธ๋ฆฌ๊ณ ์๋ ๋น ๋ฑ๋ก๊ณผ ์๋ ๋น ๋ฑ๋ก์์ ๋ ์ ์๋ค.
์๋ ๋น ๋ฑ๋ก๊ณผ ์๋ ๋น ๋ฑ๋ก์ ๊ฒฝ์ฐ์์๋ ์คํ๋ง์ ์ค๋ฅ๋ฅผ ๋ฐ์์ํจ๋ค. ConflictingBeanDefinitionException ์์ธ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ด๋ค.
์๋ ๋น ๋ฑ๋ก๊ณผ ์๋ ๋น ๋ฑ๋ก์ ๊ฒฝ์ฐ์์๋ ์๋ ๋น ๋ฑ๋ก์ด ์ฐ์ ๊ถ์ ๊ฐ๋๋ค. ์ ํํ๊ฒ ์ด์ผ๊ธฐํ๋ฉด ์๋ ๋น์ด ์๋ ๋น์ ์ค๋ฒ๋ผ์ด๋ฉ ํด๋ฒ๋ฆฐ๋ค...
๋ณดํต ์ค๋ฌด์์ ๊ฐ๋ฐ์๊ฐ ์๋์ ์ผ๋ก ์ค์ ํด์ ์ด๋ฐ ๊ฒฐ๊ณผ๊ฐ ๋์ค์ง ์๊ณ ์ฌ๋ฌ ์ค์ ์ด ๊ผฌ์ฌ์ ์ด๋ฐ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค๊ณ ํ๋ค๐ตโ๐ซ
์ก๊ธฐ ์ ๋ง ์ด๋ ค์ด ๋ฒ๊ทธ๊ฐ ๋๋ ๊ฒ์ด๋ค๐ฎโ๐จ...