๐ฏ ๋ชฉํ : @CombonentScan ์๋ ์๋ฆฌ์ ์์กด ๊ด๊ณ ์๋ ์ฃผ์
์ดํด
๐ ComponentScan
๐ ์์กด๊ด๊ณ ์๋ ์ฃผ์
- ์ค์ ์ ๋ณด์ ์ง์ Bean์ ๋ฑ๋กํ๋ ๋ฐฉ์์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ค๋ฉด, ๋ฑ๋กํด์ผ๋ ๋น์ด ์๋ฐฑ ์์ฒ๊ฐ๊ฐ ๋ ๋ ๋ฐ๋ณต๋ ์์
๊ณผ ๋๋ฝ์ ๋ฌธ์ ๋ฑ ์ฌ๋ฌ ๋ฌธ์ ๊ฐ ๋ฐ์ ํ ์๋ ์๋ค.
- ์คํ๋ง์์๋ ์ค์ ์ ๋ณด๋ฅผ ์ง์ ์์ฑํ์ง ์๊ณ ์คํ๋ง ๋น์ ๋ฑ๋กํ๋ CombpnentScan ๊ธฐ๋ฅ์ด ์์ผ๋ฉฐ ์์กด ๊ด๊ณ๋ฅผ ์๋์ผ๋ก ์ฃผ์
ํ๋ Autowired ๊ธฐ๋ฅ๋ ์๋ค.
@Configuration
@ComponentScan(
excludeFilters= @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Configuration.class
)
)
public class AutoAppConfig {
}
- @ComponentScan ์ด๋
ธํ
์ด์
๋ง Config ํ์ผ์ ๋ถ์ฌ ์ค๋ค๋ฉด ๋์ด์ ์ด ํด๋์ค ํ์ผ์์๋ ํ ์์
์ด ์๋ค.
- Bean์ผ๋ก ๋ฑ๋ก ํ๊ณ ์ ํ๋ ํด๋์ค์ @Component ์ด๋
ธํ
์ด์
๋ง ๋ถ์ฌ ์ฃผ๋ฉด๋๋ค.
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {
@Component
public class MemoryMemberRepository implements MemberRepository {
private static Map<Long, Member> store = new HashMap<>();
@Component
public class RateDiscountPolicy implements DiscountPolicy {
private int discountPercent = 10;
@Component
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
- ์ฌ๊ธฐ์ ์คํ๋ง ๋น ๊ฐ์ ์์กด๊ด๊ณ๊ฐ ํ์ํ๋ค๋ฉด ์์ฑ์์ @Autowired๋ฅผ ๋ถ์ฌ์ฃผ๋ฉด ๋ ๊ฒ์ด๋ค.
๐ Bean์ ์กฐํ
- ์ ์ ๊ฐ์ด ComponentScan์ ์ฌ์ฉํ์ฌ ๋น ๋ฑ๋ก์ ํ๋๋ผ๋ ๊ธฐ์กด AnnotationConfigApplicationContext๋ฅผ ์ฌ์ฉํด์ ์กฐํ ํ๋๊ฒ์ ๋์ผ ํ๋ค.
public class AutoAppConfigTest {
@Test
void basicScan() {
AnnotationConfigApplicationContext ac
= new AnnotationConfigApplicationContext(AutoAppConfig.class);
MemberService bean = ac.getBean(MemberService.class);
Assertions.assertThat(bean).isInstanceOf(MemberService.class);
}
}
๐ ComponentScan์ ์ค์บ ๋ฒ์์ ๋์
๐ ComponentScan์ ์ค์บ ๋ฒ์
- ComponentScan์ ์ค์บ ๋ฒ์์ ๊ธฐ๋ณธ ๊ฐ์ ์ํด์๋ ํจํค์ง๋ก๋ถํฐ ํ์ ํจํค์ง ๊น์ง๋ค.
- ํ์ฌ AutoConfig ํ์ผ์ ์์น๋ hello.core ํจํค์ง ๋ด๋ถ์ ์๋ค. AutoConfig์ ComponentScan์ ์ค์บ ๋ฒ์ ๊ธฐ๋ณธ ๊ฐ์ย hello.core ํจํค์ง๋ก ๋ถํฐ ํ์ ํจํค์ง ๊น์ง๊ฐ ๋ ๊ฒ์ด๋ค.
- @ComponentScan(basePackages = "hello.core.order") ์ ๊ฐ์ด ์ค์บ ๋ฒ์๋ฅผ ์ง์ ํ ์๋ ์๋ค.
- Config ํด๋์ค์ ์์น๋ฅผ ํ๋ก์ญํธ ์ต ์๋จ ํจํค์ง์ ๋๋ ๊ฒ์ด ์ ๋นํ ๋ฐฉ๋ฒ์ธ๊ฒ ๊ฐ๋ค. ์คํ๋ง ๋ถํธ์์๋ ์ด ๋ฐฉ๋ฒ์ ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณตํ๋ค.
ํ๋ก์ญํธ์ Application ์คํ ํด๋์ค๋ฅผ ๋ณด๋ฉด @SpringBootApplication ์ด๋
ธํ
์ด์
์ด ์๋ ์์ฑ ๋์ด ์๋๋ฐ, ์ด ์ด๋
ธํ
์ด์
๋ด๋ถ์ ComponentScan ์ด ํฌํจ ๋์ด ์๋ค.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
๐ย ComponentScan์ ์ค์บ ๋์
- @Component ๋ฟ๋ง ์๋๋ผ ์ฌ๋ฌ ์ด๋
ธํ
์ด์
์ ์ค์บ ๋์์ผ๋ก ๋๊ณ ์๋ค.
- @Component : ์ปดํฌ๋ํธ ์ค์บ์์ ์ฌ์ฉ
- @Controller : MVC ์ปจํธ๋กค๋ฌ์์ ์ฌ์ฉ
- @Service : ๋น์ฆ๋์ค ๋ก์ง์์ ์ฌ์ฉ
- @Repository : ๋ฐ์ดํฐ ์ ๊ทผ ๊ณ์ธต์์ ์ฌ์ฉ
- @Configuration : ์ค์ ์ ๋ณด์์ ์ฌ์ฉ
- ์ ์ด๋
ธํ
์ด์
๋ค์ ์์ค์ฝ๋์ @Component๋ฅผ ํฌํจํ๊ณ ์์ผ๋ฉฐ, ์๋ ์ด๋
ธํ
์ด์
์ ์คํ๋ง์ ๋ถ๊ฐ๊ธฐ๋ฅ์ ์ํ ํด์ค๋ค.
- @Controller ๋ MVC ์ปจํธ๋กค๋ฌ๋ก ์ธ์ํ๊ฒ๋๊ณ @Repository๋ ๋ฐ์ดํฐ ์ ๊ทผ ๊ณ์ธต์ผ๋ก ์ธ์๋๊ณ , ๋ฐ์ดํฐ ๊ณ์ธต์ ์์ธ๋ฅผ ์คํ๋ง ์์ธ๋ก ๋ณํํด์ค๋ค.
๐ย ComponentScan์ @Filter
@ComponentScan(
includeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class),
excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class)
)
- includeFilters๋ MyIncludeComponent ์ด๋
ธํ
์ด์
์ด ๋ถ์ ํด๋์ค๋ฅผ ๋น์ ๋ฑ๋กํ๋ค.
- excludeFilters๋ MyExcludeComponent ์ด๋
ธํ
์ด์
์ด ๋ถ์ ํด๋์ค๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ์ง ์๋๋ค.
- FilterType์ ์ต์
์
- ANNOTATION ๊ธฐ๋ณธ๊ฐ
- ASSIGNABLE_TYPE ์ง์ ํ ํ์
๊ณผ ์์ํ์
์ ์ธ์
- ASPECTJย AspectJ ํจํด์ฌ์ฉ
- REGEX ์ ๊ท ํํ์
- CUSTOM TypeFilter๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ ์ฒ๋ฆฌ.