๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
IT/Spring

[์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ] ์ธํ”„๋Ÿฐ ๊ฐ•์˜ ์ •๋ฆฌ(์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ - @Configration๊ณผ ์‹ฑ๊ธ€ํ†ค)

by YeonBu 2023. 10. 30.
728x90

/* ์ด ๊ธ€์€ ๊น€์˜ํ•œ๋‹˜์˜ ๊ฐ•์˜๋ฅผ ๋ณด๊ณ  ์ •๋ฆฌํ•˜๋ ค๊ณ  ์ž‘์„ฑํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

   ๊ฐœ์ธ์ ์ธ ๊ณต๋ถ€๋ฅผ ์œ„ํ•ด ์˜ฌ๋ฆฌ๋Š” ๊ธ€์ด๋ฏ€๋กœ ์ค‘๊ฐ„ ์ค‘๊ฐ„ ์ฝ”๋“œ๋Š” ์ƒ๋žต๋˜์—ˆ์Šต๋‹ˆ๋‹ค. */

 

 

์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜

์Šคํ”„๋ง ์ž…๋ฌธ์ž๊ฐ€ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค์–ด๊ฐ€๋ฉด์„œ ์Šคํ”„๋ง์˜ ํ•ต์‹ฌ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๊ณ , ์Šคํ”„๋ง ๊ธฐ๋ณธ๊ธฐ๋ฅผ ํ™•์‹คํžˆ ๋‹ค์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค., ์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๊ณ , ์„ฑ์žฅํ•˜๋Š” ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์–ด๋ณด์„ธ์š”! ๐Ÿ“ข

www.inflearn.com

 

 

 

 

 

@Configration๊ณผ ์‹ฑ๊ธ€ํ†ค

 

 

AppConfig

 

@Configuration
public class AppConfig {

    @Bean
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public OrderService orderService() {
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }

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

    @Bean
    public DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }

}

 

โœ” @Bean memberService โž” new MemoryMemberRepository() 

โœ” @Bean orderService โž” new MemoryMemberRepository(), new RateDiscountPolicy()

โœ” ์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ๊ฐ๊ฐ ๋‹ค๋ฅธ 2๊ฐœ์˜  MemoryMemberRepository๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด์„œ ์‹ฑ๊ธ€ํ†ค์ด ๊นจ์ง€๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค.

 โž” ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ์ด ๋ฌธ์ œ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ• ๊นŒ?

 

 

 

 

MemberServiceImpl, OrderServiceImpl

 

//ํ…Œ์ŠคํŠธ ์šฉ ์ฝ”๋“œ ์ถ”๊ฐ€
public MemberRepository getMemberRepository() {
    return memberRepository;
}

 

โœ” MemberServiceImpl, OrderServiceImpl์— ๊ฐ๊ฐ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ถ”๊ฐ€

 

 

 

 

ConfigurationSingletonTest

 

public class ConfigurationSingletonTest {

    @Test
    void configurationTest() {

        ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

        MemberServiceImpl memberService = ac.getBean("memberService", MemberServiceImpl.class);
        OrderServiceImpl orderService = ac.getBean("orderService", OrderServiceImpl.class);
        MemberRepository memberRepository = ac.getBean("memberRepository", MemberRepository.class);

        MemberRepository memberRepository1 = memberService.getMemberRepository();
        MemberRepository memberRepository2 = orderService.getMemberRepository();

        System.out.println("memberService -> memberRepository1 = " + memberRepository1);
        System.out.println("orderService -> memberRepository2 = " + memberRepository2);
        System.out.println("memberRepository = " + memberRepository);

        Assertions.assertThat(memberService.getMemberRepository()).isSameAs(memberRepository);
        Assertions.assertThat(orderService.getMemberRepository()).isSameAs(memberRepository);

    }

}

โœ” ์ฝ˜์†”์ฐฝ์„ ํ™•์ธํ•ด๋ณด๋ฉด memberRepository ์ธ์Šคํ„ด์Šค๋Š” ๋ชจ๋‘ ๊ฐ™์€ ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ณต์œ ๋˜์–ด ์‚ฌ์šฉ๋œ๋‹ค.

โœ” AppConfig์˜ ์ž๋ฐ” ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด `new MemoryMemberRepository` ํ˜ธ์ถœํ•ด์„œ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ ์–ด๋–ป๊ฒŒ ๋œ ์ผ์ผ๊นŒ?

 

 

 

 

AppConfig

 

@Configuration
public class AppConfig {

    @Bean
    public MemberService memberService() {
        System.out.println("Call AppConfig.memberService");
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public OrderService orderService() {
        System.out.println("Call AppConfig.orderService");
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }

    @Bean
    public MemberRepository memberRepository() {
        System.out.println("Call AppConfig.memberRepository");
        return new MemoryMemberRepository();
    }

    @Bean
    public DiscountPolicy discountPolicy() {
        System.out.println("Call AppConfig.discountPolicy");
        return new RateDiscountPolicy();
    }

}

 

โœ” ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๊ณ  ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๊ฐ๊ฐ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœํ•˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

โœ” ์–ด๋– ํ•œ ๋ฐฉ๋ฒ•์„ ์จ์„œ๋ผ๋„ ์Šคํ”„๋ง์ด ์‹ฑ๊ธ€ํ†ค์„ ๋ณด์žฅํ•ด์ฃผ๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ์Œ. ์–ด๋– ํ•œ ๋ฐฉ๋ฒ•์ธ์ง„ ๋‹ค์Œ ๊ฐ•์˜์—!

 

 

๐Ÿ’ก TIP

:  sout ์ข…๋ฅ˜

 

โ—พ sout : `System.out.printil()` ์ƒ์„ฑ

โ—พ soutv : ๋ณ€์ˆ˜ ์ถœ๋ ฅ

void configurationTest() {
    ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
    MemberServiceImpl memberService = ac.getBean("memberService", MemberServiceImpl.class);
    System.out.println("memberService = " + memberService);
}

โ—พ soutp : ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ฐ’ ์ถœ๋ ฅ

public void join(Member member) {
    memberRepository.save(member);
    System.out.println("member = " + member);
}

โ—พ soutm : ํ˜„์žฌ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ ์ถœ๋ ฅ

@Configuration
public class AppConfig {
    @Bean
    public MemberService memberService() {
        System.out.println("Call AppConfig.memberService");
        return new MemberServiceImpl(memberRepository());
    }
}

 

 

 

 

 

@Configration ๊ณผ ๋ฐ”์ดํŠธ์ฝ”๋“œ ์กฐ์ž‘์˜ ๋งˆ๋ฒ•

 

 

ConfigurationSingletonTest

 

@Test
void configurationDeep() {

    ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
    AppConfig bean = ac.getBean(AppConfig.class);

    System.out.println("bean = " + bean.getClass());

}

โœ” AnnotationConfigApplicationContext์— ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ธด ๊ฐ’์€ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋ก์ด ๋œ๋‹ค.

โœ” AppConfig๋„ ์Šคํ”„๋ง ๋นˆ์ด ๋˜๋ฏ€๋กœ ๋“ฑ๋กํ•˜๊ณ  ํด๋ž˜์Šค ์ •๋ณด๋ฅผ ์ถœ๋ ฅํ•ด๋ณด์ž.

โœ” ์ˆœ์ˆ˜ํ•œ ์ž๋ฐ” ํด๋ž˜์Šค๋ผ๋ฉด `class.hello.core.AppConfig ` ๋กœ ์ถœ๋ ฅ๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ ๋’ค์— CGLIB๊ฐ€ ๋ถ™์œผ๋ฉด์„œ ๋ณต์žกํ•ด์ง„ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 โž” ์Šคํ”„๋ง์ด CGLIB๋ผ๋Š” ๋ฐ”์ดํŠธ์ฝ”๋“œ ์กฐ์ž‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์„œ AppConfig ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์€ ์ž„์˜์˜ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ  ๊ทธ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋กํ–ˆ๋‹ค.

 

โœ” ์ž„์˜์˜ ๋‹ค๋ฅธ ํด๋ž˜์Šค๊ฐ€ ๋ฐ”๋กœ ์‹ฑ๊ธ€ํ†ค์ด ๋ณด์žฅ๋˜๋„๋ก ํ•ด์ค€๋‹ค.

@Bean
public MemberRepository memberRepository() {

    if (memoryMemberRepository๊ฐ€ ์ด๋ฏธ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋ก๋˜์–ด ์žˆ์œผ๋ฉด?) {
        return ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ ์ฐพ์•„์„œ ๋ฐ˜ํ™˜;
    } else { //์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ์—†์œผ๋ฉด
        ๊ธฐ์กด ๋กœ์ง์„ ํ˜ธ์ถœํ•ด์„œ MemoryMemberRepository๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋ก
        return ๋ฐ˜ํ™˜
    }

}

 

โœ” ์‹ค์ œ๋กœ CGLIB ๋‚ด๋ถ€ ๊ธฐ์ˆ ์€ ๊ต‰์žฅํžˆ ๋ณต์žกํ•˜๋‚˜, ๊ฐ„๋‹จํžˆ ์ ์œผ๋ฉด ์œ„์ฒ˜๋Ÿผ ๋˜์–ด์žˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ํ•จ.

โœ” @Bean์ด ๋ถ™์€ ๋ฉ”์„œ๋“œ๋งˆ๋‹ค ์ด๋ฏธ ์Šคํ”„๋ง ๋นˆ์ด ์กด์žฌํ•˜๋ฉด ์กด์žฌํ•˜๋Š” ๋นˆ์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ์Šคํ”„๋ง ๋นˆ์ด ์—†์œผ๋ฉด ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ์ƒ์„ฑํ•ด์„œ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ๋™์ ์œผ๋กœ ๋งŒ๋“ค์–ด์ง„๋‹ค.

 

 

 

๋งŒ์•ฝ @Configuration์„ ๋ถ™์ด์ง€ ์•Š๊ณ  @Bean๋งŒ ์ ์šฉํ•œ๋‹ค๋ฉด?

 

โ—พ AppConfig์—์„œ @Configuration์„ ์ง€์šฐ๊ณ  configurationDeep() ํ…Œ์ŠคํŠธ

 

โœ” MemberRepository๋Š” ์ด 3๋ฒˆ ํ˜ธ์ถœ๋๋‹ค. 

 - 1. @Bean์— ์˜ํ•ด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋ก๋˜๊ธฐ ์œ„ํ•ด

 - 2. memberService์—์„œ memberRepository()๋ฅผ ํ˜ธ์ถœํ•ด์„œ

 - 3. orderService์—์„œ memberRepository()๋ฅผ ํ˜ธ์ถœํ•ด์„œ

โœ” AppConfig๊ฐ€ CGLIB ๊ธฐ์ˆ ์—†์ด ์ˆœ์ˆ˜ํ•œ AppConfig๋กœ ์Šคํ”„๋ง ๋นˆ์— ๋“ฑ๋ก๋๋‹ค.

 

 

โ—พ AppConfig์—์„œ @Configuration์„ ์ง€์šฐ๊ณ  configurationTest () ํ…Œ์ŠคํŠธ

 

โœ” memberRepository์˜ ์ธ์Šคํ„ด์Šค ๊ฐ’์ด ๋‹ค๋ฅธ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๊ณ  ํ…Œ์ŠคํŠธ์— ์‹คํŒจํ•œ๋‹ค.

โœ” ์‹ฑ๊ธ€ํ†ค์ด ๋ณด์žฅ๋˜์ง€ ์•Š์Œ.

 

 

 

โž” ๊ฒฐ๋ก  : @Bean๋งŒ ์‚ฌ์šฉํ•ด๋„ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋ก์€ ๋˜๋‚˜ ์‹ฑ๊ธ€ํ†ค์„ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค. 

๊ณ ๋ฏผํ•  ๊ฒƒ ์—†์ด ์Šคํ”„๋ง ์„ค์ • ์ •๋ณด๋Š” ํ•ญ์ƒ @Configuration์„ ์‚ฌ์šฉํ•˜์ž!

 

 

 

๋ฐ˜์‘ํ˜•

'IT > Spring' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ] ์ธํ”„๋Ÿฐ ๊ฐ•์˜ ์ •๋ฆฌ(์ปดํฌ๋„ŒํŠธ ์Šค์บ” - ํ•„ํ„ฐ)  (0) 2023.11.17
[์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ] ์ธํ”„๋Ÿฐ ๊ฐ•์˜ ์ •๋ฆฌ(์ปดํฌ๋„ŒํŠธ ์Šค์บ” - ์ปดํฌ๋„ŒํŠธ ์Šค์บ”๊ณผ ์˜์กด๊ด€๊ณ„ ์ž๋™ ์ฃผ์ž…)  (0) 2023.11.02
[์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ] ์ธํ”„๋Ÿฐ ๊ฐ•์˜ ์ •๋ฆฌ(์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ - ์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ, ์‹ฑ๊ธ€ํ†ค ๋ฐฉ์‹์˜ ์ฃผ์˜์ )  (0) 2023.10.30
[์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ] ์ธํ”„๋Ÿฐ ๊ฐ•์˜ ์ •๋ฆฌ(์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ - ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ์‹ฑ๊ธ€ํ†ค, ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด)  (0) 2023.10.30
[์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ] ์ธํ”„๋Ÿฐ ๊ฐ•์˜ ์ •๋ฆฌ(์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์™€ ์Šคํ”„๋ง ๋นˆ - ๋‹ค์–‘ํ•œ ์„ค์ • ํ˜•์‹ ์ง€์›, BeanDefinition)  (1) 2023.10.28