JiwonDev

#6. ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์™€ ์Šคํ”„๋ง ๋นˆ

by JiwonDev

์•ž์—์„œ ์Šคํ”„๋ง์ด ๋‚˜์˜ค๊ฒŒ๋œ ๊ฐœ๋…์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜๋‹ค๋ฉด, ์ด๋ฒˆ ๊ธ€๋ถ€ํ„ฐ๋Š” ์Šคํ”„๋ง ์ž์ฒด๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์•Œ์•„๋ณด์ž.

*ํ•ด๋‹น ๊ธ€์€ ๊น€์˜ํ•œ๋‹˜์˜ ์ธํ”„๋Ÿฐ ๊ฐ•์˜๋ฅผ ๊ณต๋ถ€ํ•˜๊ณ  ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

 

# ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ

//์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ
ApplicationContext applicationContext =
 new AnnotationConfigApplicationContext(AppConfig.class);
@Configuration
public class AppConfig {
    @Bean
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public OrderService orderService() {
        return new OrderServiceImpl(
                memberRepository(),
                discountPolicy());
    }
    ... ์ƒ๋žต...
}
  • ApplicationContext ๋ฅผ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ผ ํ•œ๋‹ค.
  • ApplicationContext ๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค.
  • ์ฐธ๊ณ ๋กœ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ๋ณดํ†ต ์–ด๋…ธํ…Œ์ด์…˜(@) ๊ธฐ๋ฐ˜์˜ ์ž๋ฐ” ํด๋ž˜์Šค๋กœ ๋งŒ๋“ค์ง€๋งŒ, ๊ธฐ์กด์— ์„œ๋ธ”๋ฆฟ์„ ์„ค์ •ํ•˜๋˜ ๊ฒƒ์ฒ˜๋Ÿผ XML ๊ธฐ๋ฐ˜์œผ๋กœ๋„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
  • ์ž๋ฐ” ์„ค์ • ํด๋ž˜์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ(ApplicationContext)๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž.
    - new AnnotationConfigApplicationContext(appConfig.class)
    - ์ด ํด๋ž˜์Šค๋Š” ApplicationContext ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด์ด๋‹ค.

์ฐธ๊ณ ๋กœ ์ •ํ™•ํžˆ๋Š” ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋ถ€๋ฅผ ๋•Œ ์ตœ์ƒ์œ„์˜ BeanFactory์™€ ์ž์‹์ธ ApplicationContext๋ฅผ ๊ตฌ๋ถ„ํ•ด์„œ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ์ด๋Š” ๋‚˜์ค‘์— ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž. (๋ณดํ†ต BeanFactory๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ฑฐ์˜ ์—†๊ณ , AppContext๋ฅผ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ผ๊ณ  ํ•œ๋‹ค.)

 


# ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ์ƒ์„ฑ๊ณผ์ •

@1 ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ

ApplicationContext๋ผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค์— ๊ตฌํ˜„์ฒด๋ฅผ ๋“ฑ๋กํ•ด์ค˜์„œ ์‚ฌ์šฉํ•œ๋‹ค. ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑ ํ•  ๋•Œ์—๋Š” ๊ตฌ์„ฑ ์ •๋ณด๋ฅผ ๊ตฌํ˜„์ฒด์— ์ง€์ •ํ•ด์ฃผ์–ด์•ผ ํ•˜๋Š”๋ฐ, ์—ฌ๊ธฐ์—์„œ๋Š” AppConfig.class๋ฅผ ์ด์šฉํ•˜์—ฌ [์ž๋ฐ”์˜ Class ๊ฐ์ฒด]๋ฅผ ํ†ตํ•ด ๊ตฌ์„ฑ์ •๋ณด๋ฅผ ์ง€์ •ํ•˜์˜€๋‹ค. Class ๊ฐ์ฒด๊ฐ€ ๋ญ์ฃ ?

๋”๋ณด๊ธฐ

์ž๋ฐ”๋Š” Object.class ๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ๊ฐ์ฒด์˜ Class ๊ฐ์ฒด๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

Class.forName("ํŒจํ‚ค์ง€ ์ „์ฒด ๊ฒฝ๋กœ") 
ํด๋ž˜์Šค์ด๋ฆ„.class

MyHello.class
Class.forName("mypackage.core.MyHello")
Class ํด๋ž˜์Šค๋ž€ ์ž๋ฐ”์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ , ์ด๋ฅผ ์ €์žฅํ•˜์—ฌ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด์ด๋‹ค.์ฆ‰ ์‰ฝ๊ฒŒ๋งํ•ด [ํด๋ž˜์Šค์˜ ๊ตฌ์กฐ] ์ž์ฒด๋ฅผ ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๋กœ ํ‘œํ˜„ํ•ด๋†“์€ ๊ฐ์ฒด๋ผ๋Š” ๋ง์ด๋‹ค.
ํด๋ž˜์Šค์˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” Class ๊ฐ์ฒด

์ฐธ๊ณ ๋กœ ์ด๋ ‡๊ฒŒ ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด [๋‹ค๋ฅธ ๊ฐ์ฒด]์˜ ์ •๋ณด๋ฅผ ๋ถ„์„ํ•˜๋Š” ๋ฐฉ์‹์„ Reflection ๊ธฐ๋ฒ•์ด๋ผ๊ณ  ํ•œ๋‹ค. ํด๋ž˜์Šค ํŒŒ์ผ์˜ ์œ„์น˜๋‚˜ ์ด๋ฆ„๋งŒ์œผ๋กœ๋„ ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™€ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ(Hello.class) ๋งŒ๋“ค์–ด์ฃผ๋Š” ์œ ์—ฐํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋ฒ•์ด๋‹ค. ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋„ ๋ฆฌํ”Œ๋ ‰์…˜ ๊ธฐ๋ฒ•์„ ์•„์ฃผ ๋งŽ์ด ์‚ฌ์šฉ์žˆ๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.  

 

ApplicationContext applicationContext =
 new AnnotationConfigApplicationContext(AppConfig.class);

 


@2 ์Šคํ”„๋ง ๋นˆ ๋“ฑ๋ก

์ปจํ…Œ์ด๋„ˆ์— ํŒŒ๋ผ๋ฉ”ํƒ€๋กœ ๋„˜๊ฒจ์ค€ ๊ฐ์ฒด(AppConfig.class)์—์„œ @Bean ์œผ๋กœ ๋“ฑ๋ก๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์ „๋ถ€ ํ˜ธ์ถœํ•˜์—ฌ ๋ฐ˜ํ™˜ ๊ฐ’์„ ์Šคํ”„๋ง ๋นˆ ์ €์žฅ์†Œ์— ๋ชจ์•„๋‘”๋‹ค. ๋นˆ ์ด๋ฆ„์€ ๋ฉ”์„œ๋“œ ๋ช…์œผ๋กœ ์ง€์ •๋˜๋ฉฐ ์›ํ•œ๋‹ค๋ฉด ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๊ธดํ•˜๋‹ค. @Bean(name="...") ์ฐธ๊ณ ๋กœ ๋นˆ์˜ ์ด๋ฆ„์€ ํ•ญ์ƒ ๋‹ค๋ฅด๊ฒŒ ๋ถ€์—ฌํ•ด์ฃผ์–ด์•ผํ•˜๋Š”๋ฐ, ๊ฐ™์€ ์ด๋ฆ„์„ ๋ถ€์—ฌํ•˜๋ฉด ๋นˆ ์ €์žฅ์†Œ์—์žˆ๋Š” ๊ธฐ์กด์˜ ๋นˆ์„ ๋ฎ์–ด๋ฒ„๋ฆฌ๊ฑฐ๋‚˜ ๋ฌด์‹œ๋˜์–ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. (* ์š”์ฆ˜์€ ์Šคํ”„๋ง ๋ถ€ํŠธ๊ฐ€ ์ด๋Ÿฐ ์„ค์ • ์‹ค์ˆ˜๋ฅผ ์˜ค๋ฅ˜๋กœ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์•Œ๋ ค์ค€๋‹ค. )

 


@3 ์Šคํ”„๋ง ๋นˆ ์˜์กด๊ด€๊ณ„ ์„ค์ •

์ €์žฅ์†Œ์— ๋“ฑ๋ก๋œ ๋นˆ๋“ค์˜ ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•œ๋‹ค. ์‹ค์ œ ์Šคํ”„๋ง ๋นˆ์—์„œ ์˜์กด๊ด€๊ณ„์ธ ๊ฐ์ฒด์˜ ์ฐธ์กฐ ๊ฐ’๋“ค์ด ์—ฐ๊ฒฐ๋œ๋‹ค. ์—ฐ๊ฒฐ์ด๋ผ๋Š”๊ฒŒ ๋‹จ์ˆœํžˆ ์ž๋ฐ” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด์™€๋Š” ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค. (*์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ)

์ด์ฒ˜๋Ÿผ ์Šคํ”„๋ง์€ ๋นˆ์„ ์ƒ์„ฑํ•˜๋Š” ๋‹จ๊ณ„์™€ ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๋‹จ๊ณ„๊ฐ€ ๋‚˜๋ˆ„์–ด์ ธ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์œ„์˜ ์˜ˆ์ œ์ฒ˜๋Ÿผ ์ž๋ฐ” ์ฝ”๋“œ๋กœ ์Šคํ”„๋ง๋นˆ์„ ๋“ฑ๋กํ•˜๋ฉด ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด์„œ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…๋„ ํ•œ๋ฒˆ์— ์ฒ˜๋ฆฌ๋˜๋Š”๋ฐ, ์ด๋Š” ๋‚˜์ค‘์— '์˜์กด๊ด€๊ณ„ ์ž๋™ ์ฃผ์ž…'์„ ๋ฐฐ์šฐ๋ฉด์„œ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž.

 


# ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋ก๋œ ์Šคํ”„๋ง ๋นˆ ์กฐํšŒํ•˜๊ธฐ

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ(JUnit5)๋ฅผ ์ด์šฉํ•ด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋ก๋œ ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•ด๋ณด์ž. ์ฐธ๊ณ ๋กœ ๋“ฑ๋ก๋œ ๋นˆ๋“ค์˜ ์ด๋ฆ„์€ AppContext ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋กœ ์–ป์–ด์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ๋‚ด๊ฐ€ ๋“ฑ๋กํ•œ ๋นˆ ์ด์™ธ์— ์Šคํ”„๋ง์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋นˆ๋“ค๋„ ์žˆ์Œ์„ ์œ ์˜ํ•˜์ž.

class ApplicationContextInfoTest {
    AnnotationConfigApplicationContext ac = new
            AnnotationConfigApplicationContext(AppConfig.class);

    @Test
    @DisplayName("๋ชจ๋“  ๋นˆ ์ถœ๋ ฅํ•˜๊ธฐ")
    void findAllBean() {
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            Object bean = ac.getBean(beanDefinitionName);
            System.out.println("name=" + beanDefinitionName + " object=" + bean);
        }
    }
}

 

๋˜ํ•œ getBeanDefinition์„ ๋น„๊ตํ•ด์„œ ๋‚ด๊ฐ€ ๋“ฑ๋กํ•œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋นˆ(appConfig, memberService...)๋งŒ ํ™•์ธํ• ์ˆ˜๋„ ์žˆ๋‹ค.

import org.springframework.beans.factory.config.BeanDefinition;

    @Test
    @DisplayName("์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋นˆ ์ถœ๋ ฅํ•˜๊ธฐ")
    void findApplicationBean() {
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            BeanDefinition beanDefinition =
                    ac.getBeanDefinition(beanDefinitionName);
            //Role ROLE_APPLICATION: ์ง์ ‘ ๋“ฑ๋กํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋นˆ
            //Role ROLE_INFRASTRUCTURE: ์Šคํ”„๋ง์ด ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋นˆ
            if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
                Object bean = ac.getBean(beanDefinitionName);
                System.out.println("name=" + beanDefinitionName + " object=" +
                        bean);
            }
        }
    }

 


@1 Bean ์กฐํšŒ - ๊ธฐ๋ณธ

์œ„์— ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ์ž๋งŒ, ๊ธฐ๋ณธ์ ์œผ๋กœ ๋นˆ์€ AppContext์˜ ์•„๋ž˜ ๋ฉ”์„œ๋“œ๋กœ ์กฐํšŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ํ•ด๋‹น ๋นˆ์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด NoSuchBeanDefinitionException ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

  • getBean("Bean ์ด๋ฆ„", ํƒ€์ž…)
  • getBean(ํƒ€์ž…)
import org.junit.jupiter.api.Assertions; // Assertions๊ฐ€ ๊ฐ™์€ ์ด๋ฆ„์ด 2๊ฐœ์ž„์„ ์œ ์˜ํ•˜์ž.
import static org.assertj.core.api.Assertions.*;

class ApplicationContextBasicFindTest {
    AnnotationConfigApplicationContext ac = new
            AnnotationConfigApplicationContext(AppConfig.class);

    @Test
    @DisplayName("๋นˆ ์ด๋ฆ„์œผ๋กœ ์กฐํšŒ")
    void findBeanByName() {
        MemberService memberService = ac.getBean("memberService",
                MemberService.class);
        assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
    }

    @Test
    @DisplayName("์ด๋ฆ„ ์—†์ด ํƒ€์ž…๋งŒ์œผ๋กœ ์กฐํšŒ")
    void findBeanByType() {
        MemberService memberService = ac.getBean(MemberService.class);
        assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
    }

    @Test
    @DisplayName("๊ตฌ์ฒด ํƒ€์ž…์œผ๋กœ ์กฐํšŒ")
    void findBeanByName2() {
        MemberServiceImpl memberService = ac.getBean("memberService",
                MemberServiceImpl.class);
        assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
    }

    @Test
    @DisplayName("๋นˆ ์ด๋ฆ„์œผ๋กœ ์กฐํšŒ์‹คํŒจ")
    void findBeanByNameX() {
        //ac.getBean("xxxxx", MemberService.class); ํ…Œ์ŠคํŠธ
        Assertions.assertThrows(NoSuchBeanDefinitionException.class, () ->
                ac.getBean("xxxxx", MemberService.class));
    }
}

* ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ์—ญํ• ๊ณผ ๊ตฌํ˜„์„ ๋ถ„๋ฆฌํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค. ์œ„์˜ ์˜ˆ์ œ์ฒ˜๋Ÿผ ์Šคํ”„๋ง ๋นˆ์„ ์กฐํšŒํ•  ๋•Œ ๊ตฌํ˜„์ฒด๋ฅผ ์ด์šฉํ•ด ๊ตฌ์ฒด์ ์œผ๋กœ ์กฐํšŒํ•˜๋ฉด ์œ ์—ฐ์„ฑ์ด ๋–จ์–ด์ง์„ ์œ ์˜ํ•˜์ž.


@2 Bean ์กฐํšŒ - ๋™์ผํ•œ ํƒ€์ž…์ด 2๊ฐœ ์ด์ƒ์ธ ๊ฒฝ์šฐ

getBean์„ ์ด์šฉํ•ด ํƒ€์ž…์œผ๋กœ ๋นˆ์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค ํ–ˆ๋Š”๋ฐ, ๋งŒ์•ฝ ํƒ€์ž…์ด ๊ฐ™๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์„๊นŒ? ์ด๋Š” ac.getBeansOfType()์„ ์ด์šฉํ•˜์—ฌ ํ•ด๋‹น ํƒ€์ž…์˜ ๋ชจ๋“  ๋นˆ์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

* ํ…Œ์ŠคํŠธ๋ฅผ ํŽธํ•˜๊ฒŒ ํ•˜๊ธฐ์œ„ํ•ด ์ฝ”๋“œ์•ˆ์— ๊ฐ„๋‹จํ•˜๊ฒŒ ํ…Œ์ŠคํŠธ์šฉ AppConfig ๊ฐ์ฒด(SameBeanConfig)๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

class ApplicationContextSameBeanFindTest {
    AnnotationConfigApplicationContext ac = new
            AnnotationConfigApplicationContext(SameBeanConfig.class);

    @Test
    @DisplayName("ํƒ€์ž…์œผ๋กœ ์กฐํšŒ์‹œ ๊ฐ™์€ ํƒ€์ž…์ด ๋‘˜ ์ด์ƒ ์žˆ์œผ๋ฉด, ์ค‘๋ณต ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค")
    void findBeanByTypeDuplicate() {
        //DiscountPolicy bean = ac.getBean(MemberRepository.class);
        assertThrows(NoUniqueBeanDefinitionException.class, () ->
                ac.getBean(MemberRepository.class));
    }

    @Test
    @DisplayName("ํƒ€์ž…์œผ๋กœ ์กฐํšŒ์‹œ ๊ฐ™์€ ํƒ€์ž…์ด ๋‘˜ ์ด์ƒ ์žˆ์œผ๋ฉด, ๋นˆ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋ฉด ๋œ๋‹ค")
    void findBeanByName() {
        MemberRepository memberRepository = ac.getBean("memberRepository1",
                MemberRepository.class);
        assertThat(memberRepository).isInstanceOf(MemberRepository.class);
    }

    @Test
    @DisplayName("ํŠน์ • ํƒ€์ž…์„ ๋ชจ๋‘ ์กฐํšŒํ•˜๊ธฐ")
    void findAllBeanByType() {
        Map<String, MemberRepository> beansOfType =
                ac.getBeansOfType(MemberRepository.class);
        for (String key : beansOfType.keySet()) {
            System.out.println("key = " + key + " value = " +
                    beansOfType.get(key));
        }
        System.out.println("beansOfType = " + beansOfType);
        // ๊ฐ™์€ ํƒ€์ž…์€ 2๊ฐœ์—ฌ์•ผ ํ•œ๋‹ค.
        assertThat(beansOfType.size()).isEqualTo(2);
    }
    
    // ํ…Œ์ŠคํŠธ์šฉ AppConfig ์‚ฌ์šฉ. ํ…Œ์ŠคํŠธ๋ผ์„œ ๋Œ€์ถฉ ๋งŒ๋“ค์—ˆ๋‹ค.
    @Configuration
    static class SameBeanConfig {
        @Bean
        public MemberRepository memberRepository1() {
            return new MemoryMemberRepository();
        }

        @Bean
        public MemberRepository memberRepository2() {
            return new MemoryMemberRepository();
        }
    }
}

ํŠน์ • ํƒ€์ž…์„ ๋ชจ๋‘ ์กฐํšŒํ•˜๊ธฐ ๊ฒฐ๊ณผ


@3 Bean ์กฐํšŒ - ์ƒ์†๊ด€๊ณ„

๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ์กฐํšŒํ•˜๋ฉด, ์ž์‹ ํƒ€์ž…๋„ ํ•จ๊ป˜ ์กฐํšŒํ•œ๋‹ค. ์ฆ‰ Object๋กœ ์กฐํšŒํ•˜๋ฉด ๋ชจ๋“  ์Šคํ”„๋ง ๋นˆ์ด ๋‚˜์˜ค๊ฒŒ ๋œ๋‹ค. ์ค‘๋ณต์„ ํ™•์ธํ•  ๋•Œ ์ƒ์†๊ด€๊ณ„๋ฅผ ์œ ์˜ํ•˜์—ฌ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋„๋ก ํ•˜์ž. 

1๋ฒˆ ๊ฐ์ฒด์˜ ๋นˆ์„ ์กฐํšŒํ•˜๋ฉด, ๋ชจ๋“  ์ž์‹์ด ํ•จ๊ป˜ ๋ฐ˜ํ™˜๋œ๋‹ค.

class ApplicationContextExtendsFindTest {
    AnnotationConfigApplicationContext ac = new
            AnnotationConfigApplicationContext(TestConfig.class);

    @Test
    @DisplayName("๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ์กฐํšŒ์‹œ, ์ž์‹์ด ๋‘˜ ์ด์ƒ ์žˆ์œผ๋ฉด, ์ค‘๋ณต ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค")
    void findBeanByParentTypeDuplicate() {
        //DiscountPolicy bean = ac.getBean(DiscountPolicy.class);
        assertThrows(NoUniqueBeanDefinitionException.class, () ->
                ac.getBean(DiscountPolicy.class));
    }

    @Test
    @DisplayName("๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ์กฐํšŒ์‹œ, ์ž์‹์ด ๋‘˜ ์ด์ƒ ์žˆ์œผ๋ฉด, ๋นˆ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋ฉด ๋œ๋‹ค")
    void findBeanByParentTypeBeanName() {
        DiscountPolicy rateDiscountPolicy = ac.getBean("rateDiscountPolicy",
                DiscountPolicy.class);
        assertThat(rateDiscountPolicy).isInstanceOf(RateDiscountPolicy.class);
    }

    @Test
    @DisplayName("ํŠน์ • ํ•˜์œ„ ํƒ€์ž…์œผ๋กœ ์กฐํšŒ")
    void findBeanBySubType() {
        RateDiscountPolicy bean = ac.getBean(RateDiscountPolicy.class);
        assertThat(bean).isInstanceOf(RateDiscountPolicy.class);
    }

    @Test
    @DisplayName("๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ๋ชจ๋‘ ์กฐํšŒํ•˜๊ธฐ")
    void findAllBeanByParentType() {
        Map<String, DiscountPolicy> beansOfType =
                ac.getBeansOfType(DiscountPolicy.class);
        assertThat(beansOfType.size()).isEqualTo(2);
        for (String key : beansOfType.keySet()) {
            System.out.println("key = " + key + " value=" +
                    beansOfType.get(key));
        }
    }

    @Test
    @DisplayName("๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ๋ชจ๋‘ ์กฐํšŒํ•˜๊ธฐ - Object")
    void findAllBeanByObjectType() {
        Map<String, Object> beansOfType = ac.getBeansOfType(Object.class);
        for (String key : beansOfType.keySet()) {
            System.out.println("key = " + key + " value=" +
                    beansOfType.get(key));
        }
    }

    @Configuration
    static class TestConfig {
        @Bean
        public DiscountPolicy rateDiscountPolicy() {
            return new RateDiscountPolicy();
        }

        @Bean
        public DiscountPolicy fixDiscountPolicy() {
            return new FixDiscountPolicy();
        }
    }
}

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ