[Spring] @ComponentScan

Goghยท2023๋…„ 1์›” 2์ผ
0

Spring

๋ชฉ๋ก ๋ณด๊ธฐ
6/23

๐ŸŽฏ ๋ชฉํ‘œ : @CombonentScan ์ž‘๋™ ์›๋ฆฌ์™€ ์˜์กด ๊ด€๊ณ„ ์ž๋™ ์ฃผ์ž… ์ดํ•ด

๐Ÿ“’ ComponentScan

๐Ÿ“Œ ์˜์กด๊ด€๊ณ„ ์ž๋™ ์ฃผ์ž…

  • ์„ค์ • ์ •๋ณด์— ์ง์ ‘ Bean์„ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค๋ฉด, ๋“ฑ๋กํ•ด์•ผ๋  ๋นˆ์ด ์ˆ˜๋ฐฑ ์ˆ˜์ฒœ๊ฐœ๊ฐ€ ๋ ๋•Œ ๋ฐ˜๋ณต๋œ ์ž‘์—…๊ณผ ๋ˆ„๋ฝ์˜ ๋ฌธ์ œ ๋“ฑ ์—ฌ๋Ÿฌ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
  • ์Šคํ”„๋ง์—์„œ๋Š” ์„ค์ • ์ •๋ณด๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ  ์Šคํ”„๋ง ๋นˆ์„ ๋“ฑ๋กํ•˜๋Š” CombpnentScan ๊ธฐ๋Šฅ์ด ์žˆ์œผ๋ฉฐ ์˜์กด ๊ด€๊ณ„๋ฅผ ์ž๋™์œผ๋กœ ์ฃผ์ž…ํ•˜๋Š” Autowired ๊ธฐ๋Šฅ๋„ ์žˆ๋‹ค.
@Configuration
@ComponentScan(
// ๊ธฐ์กด ์žˆ๋˜ Config ํŒŒ์ผ์„ ์ œ์™ธํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ๋กํ•œ filter
        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๋ผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ด์„œ ์ฒ˜๋ฆฌ.
profile
์ปดํ“จํ„ฐ๊ฐ€ ํ• ์ผ์€ ์ปดํ“จํ„ฐ๊ฐ€

0๊ฐœ์˜ ๋Œ“๊ธ€