๐Ÿง‘๐Ÿปโ€๐Ÿ’ป์ปดํฌ๋„ŒํŠธ ์Šค์บ”(@ComponentScan)

DEVJUNยท2021๋…„ 12์›” 23์ผ
0
post-thumbnail

์•ž์„œ ์Šคํ”„๋ง ๋นˆ์„ ๋“ฑ๋กํ•  ๋•Œ @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์˜ ๋กœ๊ทธ๋ฅผ ๋ณด๋ฉด ์Šค์บ”์ด ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•œ ๊ฒƒ์„ ๋ณผ์ˆ˜ ์žˆ๋‹ค.๐Ÿ˜ฒ๐Ÿ‘๐Ÿป๐Ÿ‘๐Ÿป

๊ทธ๋ฆผ์„ ํ†ตํ•ด ๋™์ž‘ ๊ณผ์ •์„ ์•Œ์•„๋ณด์ž!

  1. @Component Scan์€ @Component๊ฐ€ ๋ถ™์€ ๋ชจ๋“  ํด๋ž˜์Šค๋ฅผ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•œ๋‹ค. ์ด๋•Œ ์Šคํ”„๋ง ๋นˆ์˜ ๊ธฐ๋ณธ ์ด๋ฆ„์€ ํด๋ž˜์Šค๋ช…์ด๊ธด ํ•˜์ง€๋งŒ ๋งจ ์•ž๊ธ€์ž๋Š” ์†Œ๋ฌธ์ž๋กœ ๋“ฑ๋ก๋œ๋‹ค.
  1. ์ƒ์„ฑ์ž์— @Autowired๋ฅผ ์ง€์ •ํ•˜๋ฉด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ž๋™์œผ๋กœ ํ•ด๋‹น ์Šคํ”„๋ง ๋นˆ์„ ์ฐพ์•„์„œ ์ฃผ์ž…ํ•ด์ค€๋‹ค.
    getBean(MemberRepository.class)์™€ ๋™์ผํ•˜๋‹ค๊ณ  ๋ณด๋ฉด ๋œ๋‹ค.

    ์ƒ์„ฑ์ž์— ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๋งŽ์•„๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹ค ์ฐพ์•„์„œ ์ฃผ์ž…ํ•ด์ค€๋‹ค.



๋ชจ๋“  ์ž๋ฐ” ํด๋ž˜์Šค๋ฅผ ๋‹ค ์Šค์บ”ํ•˜๋ฉด ์‹œ๊ฐ„์ด ์˜ค๋ž˜๊ฑธ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•œ ์œ„์น˜๋ถ€ํ„ฐ ์ง€์ •ํ•˜์—ฌ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ๋“ค์–ด ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค๋ฉด

  • com.hello
  • com.hello.service
  • com.hello.repositroy

com.hello๊ฐ€ ํ”„๋กœ์ ํŠธ ์‹œ์ž‘ ๋ฃจํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณดํ†ต AppConfig๊ฐ™์€ ๋ฉ”์ธ ์„ค์ • ์ •๋ณด๋ฅผ ๋‘๊ณ , @ComponentScan์• ๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ธ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด com.hello๋ฅผ ํฌํ•จํ•œ ํ•˜์œ„ ํŒจํ‚ค์ง€๋“ค์€ ๋ชจ๋‘ ์ž๋™์œผ๋กœ ์ปดํฌ๋„ŒํŠธ ์Šค์บ”์˜ ๋Œ€์ƒ์ด ๋œ๋‹ค ๋ณดํ†ต์€ ์ด๋Ÿฐ ๋ฃฐ์„ ๋”ฐ๋ฅธ๋‹ค.


๐Ÿง‘๐Ÿปโ€๐Ÿ’ป์ค‘๋ณต ๋“ฑ๋ก๊ณผ ์ถฉ๋Œ๐Ÿ˜ฑโ—๏ธ

์ปดํฌ๋„ŒํŠธ ์Šค์บ”์—์„œ ๊ฐ™์€ ๋นˆ ์ด๋ฆ„์„ ๋“ฑ๋กํ•˜๋ฉด ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•œ๋‹ค.
์œ„์—์„œ ๋ณด์•˜๋“ฏ ์ปดํฌ๋„ŒํŠธ ์Šค์บ”์œผ๋กœ ์ž๋™์œผ๋กœ ์Šคํ”„๋ง ๋นˆ์„ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๊ณ  ์ˆ˜๋™์œผ๋กœ ์Šคํ”„๋ง ๋นˆ์„ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

์ถฉ๋Œ์€ 2๊ฐ€์ง€ ๊ฒฝ์šฐ๋กœ ๋‚  ์ˆ˜ ์žˆ๋‹ค. ์ž๋™ ๋นˆ ๋“ฑ๋ก๊ณผ ์ž๋™ ๋นˆ ๋“ฑ๋ก
๊ทธ๋ฆฌ๊ณ  ์ˆ˜๋™ ๋นˆ ๋“ฑ๋ก๊ณผ ์ž๋™ ๋นˆ ๋“ฑ๋ก์—์„œ ๋‚  ์ˆ˜ ์žˆ๋‹ค.


์ž๋™ ๋นˆ ๋“ฑ๋ก๊ณผ ์ž๋™ ๋นˆ ๋“ฑ๋ก์˜ ๊ฒฝ์šฐ์—์„œ๋Š” ์Šคํ”„๋ง์€ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. ConflictingBeanDefinitionException ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์ˆ˜๋™ ๋นˆ ๋“ฑ๋ก๊ณผ ์ž๋™ ๋นˆ ๋“ฑ๋ก์˜ ๊ฒฝ์šฐ์—์„œ๋Š” ์ˆ˜๋™ ๋นˆ ๋“ฑ๋ก์ด ์šฐ์„ ๊ถŒ์„ ๊ฐ–๋Š”๋‹ค. ์ •ํ™•ํ•˜๊ฒŒ ์ด์•ผ๊ธฐํ•˜๋ฉด ์ˆ˜๋™ ๋นˆ์ด ์ž๋™ ๋นˆ์„ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•ด๋ฒ„๋ฆฐ๋‹ค...

๋ณดํ†ต ์‹ค๋ฌด์—์„œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์˜๋„์ ์œผ๋กœ ์„ค์ •ํ•ด์„œ ์ด๋Ÿฐ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค์ง„ ์•Š๊ณ  ์—ฌ๋Ÿฌ ์„ค์ •์ด ๊ผฌ์—ฌ์„œ ์ด๋Ÿฐ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค๊ณ  ํ•œ๋‹ค๐Ÿ˜ตโ€๐Ÿ’ซ
์žก๊ธฐ ์ •๋ง ์–ด๋ ค์šด ๋ฒ„๊ทธ๊ฐ€ ๋˜๋Š” ๊ฒƒ์ด๋‹ค๐Ÿ˜ฎโ€๐Ÿ’จ...

์ถœ์ฒ˜

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard

profile
๐Ÿง‘๐Ÿปโ€๐Ÿ’ปiOS

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