JiwonDev

#7. ์Šคํ”„๋ง์˜ ์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ (@Configuration)

by JiwonDev

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

 

 

# ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜

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

 

๊ธฐ์กด์˜ ์ž๋ฐ” ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ DI ์ปจํ…Œ์ด๋„ˆ(AppConfig)๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒฝ์šฐ, ๊ณ ๊ฐ์˜ ์š”์ฒญํ•  ๋•Œ ๋งˆ๋‹ค ๊ฐ์ฒด๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜๊ณ  ์†Œ๋ฉธํ•œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ DI ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ตณ์ด ์ด๋ ‡๊ฒŒ ์ˆ˜๋ฐฑ, ์ˆ˜๋งŒ๊ฐœ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค๊ฐ€ ์†Œ๋ฉธ์‹œํ‚ฌ ํ•„์š”๊ฐ€ ์—†์„๊นŒ? ์ด๋Š” DI ์ปจํ…Œ์ด๋„ˆ ๊ฐ์ฒด๋ฅผ ํ•˜๋‚˜๋งŒ ๋งŒ๋“ค์–ด์„œ ๊ณต์œ ํ•˜๋„๋ก ์„ค๊ณ„ํ•˜๋ฉด ๋œ๋‹ค. ์ด๋ฅผ ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์ด๋ผ ํ•˜๋ฉฐ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ์‚ฌ์šฉํ•œ๋‹ค.

 


# ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด

๊ทธ๋Ÿฐ๋ฐ ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์€ ๊ตณ์ด ์Šคํ”„๋ง์ด ์•„๋‹ˆ๋”๋ผ๋„, ๋‚ด๊ฐ€ ์ง์ ‘ DI ์ปจํ…Œ์ด๋„ˆ์— ํŒจํ„ด์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ์•„๋‹๊นŒ?

 

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

public class SingletonService {
    //1. static ์˜์—ญ์— ๊ฐ์ฒด๋ฅผ ๋”ฑ 1๊ฐœ๋งŒ ์ƒ์„ฑํ•ด๋‘”๋‹ค.
    // ๋˜๋Š” getInstance() ํ˜ธ์ถœ ์‹œ, ํ˜„์žฌ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๊ฐ€ ์žˆ๋Š”์ง€ ์ฒดํฌํ•˜์—ฌ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค.
    private static final SingletonService instance = new SingletonService();
   
   //2. getInstance()๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    public static SingletonService getInstance() {
        return instance;
    }

    //3. ์ƒ์„ฑ์ž๋ฅผ private์œผ๋กœ ์„ ์–ธํ•ด์„œ ์™ธ๋ถ€์—์„œ new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ ๊ฐ์ฒด ์ƒ์„ฑ์„ ๋ชปํ•˜๊ฒŒ ๋ง‰๋Š”๋‹ค.
    private SingletonService() {
    }

    public void logic() {
        System.out.println("์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด ๋กœ์ง ํ˜ธ์ถœ");
    }
}

ํ•˜์ง€๋งŒ ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ์ง์ ‘ ๊ตฌํ˜„ํ–ˆ์„ ๋•Œ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฌธ์ œ์ ์„ ๋งž์ดํ•˜๊ฒŒ ๋œ๋‹ค.

  • ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐœ๋ฐœ์ž์˜ ์ฝ”๋“œ ์ž์ฒด๊ฐ€ ๋งŽ์ด ๋“ค์–ด๊ฐ„๋‹ค.
  • ์˜์กด๊ด€๊ณ„์ƒ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ตฌํ˜„์ฒด ํด๋ž˜์Šค์— ์˜์กดํ•œ๋‹ค. [ ...=๊ตฌํ˜„์ฒด.getInstance() ] -> DIP, OCP ์œ„๋ฐ˜
  • ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์–ด๋ ต๊ณ , ์ƒ์†๋„ ์–ด๋ ต๊ณ , ๋‚ด๋ถ€ ์†์„ฑ์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ ๊นŒ๋‹ค๋กญ๋‹ค.
  • ์ฆ‰ ๊ฒฐ๊ณผ์ ์œผ๋กœ ์œ ์—ฐ์„ฑ์ด ๋–จ์–ด์ง„๋‹ค. (์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์•ˆ์ข‹์€ ์ฝ”๋“œ, ์•ˆํ‹ฐํŒจํ„ด์ด๋ผ๊ณ  ๋ถˆ๋ฆฌ๊ธฐ๋„ ํ•œ๋‹ค.)

 


# ์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ

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

  • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ์‹ฑ๊ธ€ํ„ด ํŒจํ„ด์„ ์ ์šฉํ•˜์ง€ ์•Š์•„๋„, ๊ธฐ๋ณธ์ ์œผ๋กœ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๊ฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.
    - ์ปจํ…Œ์ด๋„ˆ๋Š” ๊ฐ์ฒด๋ฅผ ํ•˜๋‚˜๋งŒ ์ƒ์„ฑํ•ด์„œ ๊ด€๋ฆฌํ•œ๋‹ค.
  • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ ์—ญํ• ์„ ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ์ƒ์„ฑ/๊ด€๋ฆฌํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์‹ฑ๊ธ€ํ†ค ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ผ๊ณ ๋„ ํ•œ๋‹ค.
  • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ์ด๋Ÿฐ ๊ธฐ๋Šฅ ๋•๋ถ„์— ์‹ฑ๊ธ€ํ„ด ํŒจํ„ด์˜ ๋‹จ์ ์„ ํ•ด๊ฒฐํ•˜๋ฉด์„œ, ๊ฐ์ฒด๋ฅผ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ์œ ์ง€ํ•œ๋‹ค.
  • ๋ฌด์—‡๋ณด๋‹ค ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ์œ„ํ•œ ์ง€์ €๋ถ„ํ•œ ์ฝ”๋“œ๊ฐ€ ํ•„์š”์—†๋‹ค.
  • DIP, OCP, ํ…Œ์ŠคํŠธ, Private ์ƒ์„ฑ์ž๋กœ๋ถ€ํ„ฐ ์ž์œ ๋กญ๊ฒŒ ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 


# ์‹ฑ๊ธ€ํ†ค & ์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ ๋ฐฉ์‹์˜ ์ฃผ์˜์ 

์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ์—ฌ๋Ÿฌ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•˜๋‚˜์˜ ๊ฐ™์€ ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๋ฅผ ๊ณต์œ ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๊นŒ๋จน์œผ๋ฉด ์•ˆ๋œ๋‹ค. ๋‹น์—ฐํ•œ ์‚ฌ์‹ค์ธ ๋“ฏ ํ•ด๋„ ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด์— ์ƒํƒœ๋ฅผ ์œ ์ง€(Stateful)ํ•˜๋„๋ก ์„ค๊ณ„ํ•˜๋Š” ์‹ค์ˆ˜๋ฅผ ์ข…์ข… ๋ณผ ์ˆ˜์žˆ๋‹ค.

  • ๋ฌด์ƒํƒœ(stateless)ํ•˜๊ฒŒ ์„ค๊ณ„ํ•ด์•ผํ•œ๋‹ค.
  • ํŠน์ • ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์˜์กด์ ์ธ ํ•„๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ์•ˆ๋œ๋‹ค.
  • ํŠน์ • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ํ•„๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ์•ˆ๋œ๋‹ค.
  • ๊ทธ๋ž˜์„œ ๊ฐ€๊ธ‰์  ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด๋Š” '์ฝ๊ธฐ' ๋งŒ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
  • ํ•„๋“œ ๋Œ€์‹ ์— ์ž๋ฐ”์—์„œ ๊ณต์œ ๋˜์ง€ ์•Š๋Š” ์ง€์—ญ๋ณ€์ˆ˜, ํŒŒ๋ผ๋ฉ”ํƒ€, ThreadLocal๋“ฑ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค

์ด๋ฅผ ์œ ์˜ํ•˜์ง€ ์•Š๊ณ  ์Šคํ”„๋ง ๋นˆ์˜ ํ•„๋“œ์— ํด๋ผ์ด์–ธํŠธ ๊ฐ„ ๊ณต์œ  ๊ฐ’์„ ์„ค์ •ํ•˜๋ฉด, ์ •๋ง ํ•ด๊ฒฐํ•˜๊ธฐ ์–ด๋ ค์šด ํฐ ์žฅ์• ๊ฐ€ ํ„ฐ์ง€๊ฒŒ ๋œ๋‹ค. ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด์ธ ์Šคํ”„๋ง ๋นˆ์€ ํ•ญ์ƒ ๋ฌด์ƒํƒœ(Stateless)๋กœ ์„ค๊ณ„ํ•ด์•ผ ํ•จ์„ ์ ˆ๋Œ€ ๊นŒ๋จน์ง€ ๋ง์ž.

package hello.core.singleton;

public class StatefulService {
    private int price; //์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋Š” ํ•„๋“œ

    public void order(String name, int price) {
        System.out.println("name = " + name + " price = " + price);
        this.price = price; //์—ฌ๊ธฐ๊ฐ€ ๋ฌธ์ œ! ๊ณต์œ ํ•„๋“œ๋Š” ํ•ญ์ƒ ์กฐ์‹ฌํ•ด์•ผ ํ•œ๋‹ค.
        // ์‹ค์ œ ์‚ฌ์šฉ์—์„œ ์ฃผ๋ฌธ ๊ธˆ์•ก์ด ํด๋ผ์ด์–ธํŠธ๊ฐ„์— ์„œ๋กœ ์˜ํ–ฅ์„ ๋ผ์น˜๊ฒŒ ๋œ๋‹ค.
    }

    public int getPrice() {
        return price;
    }

 


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

์•„๋ž˜ ์ปจํ…Œ์ด๋„ˆ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์‚ดํŽด๋ณด์ž. ๋ฌด์–ธ๊ฐ€ ์ด์ƒํ•œ ์ ์ด ์žˆ์ง€ ์•Š์€๊ฐ€?

  • memberService ๋นˆ์„ ๋งŒ๋“œ๋Š” ์ฝ”๋“œ์— memberRepository()๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
    - memberService Bean์— new MemoryMemberRepository๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.
  • OrderService ๋นˆ์„ ๋งŒ๋“œ๋Š” ์ฝ”๋“œ์— memberRepository()๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
    - OrderService Bean์— new MemoryMemberRepository๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

๊ทธ๋ ‡๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ๋Š” ๋‹ค๋ฅธ 2๊ฐœ์˜ ๋นˆ์—, ๊ฐ™์€ ๊ตฌํ˜„์ฒด๊ฐ€ ์ƒ์„ฑ๋˜๋ฉฐ ์‹ฑ๊ธ€ํ†ค์— ๊นจ์ง€๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค. ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ์ด ๋ฌธ์ œ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ–ˆ์„๊นŒ?

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

    @Bean
    public OrderService orderService() {
        return new OrderServiceImpl(
                memberRepository(),
                discountPolicy());
    }
     ... ์ƒ๋žต ...
}

 

์ง์ ‘ ์‹คํ—˜์„ ํ†ตํ•ด ์•Œ์•„๋ณด์ž.

@Configuration
public class AppConfig {
    @Bean
    public MemberService memberService() {
        //1๋ฒˆ
        System.out.println("call AppConfig.memberService");
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public OrderService orderService() {
        //1๋ฒˆ
        System.out.println("call AppConfig.orderService");
        return new OrderServiceImpl(
                memberRepository(),
                discountPolicy());
    }

    @Bean
    public MemberRepository memberRepository() {
        //2๋ฒˆ? 3๋ฒˆ?
        System.out.println("call AppConfig.memberRepository");
        return new MemoryMemberRepository();
    }

    @Bean
    public DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }
}
//์ฝ˜์†” ์ถœ๋ ฅ ๊ฒฐ๊ณผ. ๋†€๋ž๊ฒŒ๋„ ๊ฐ๊ฐ 1๋ฒˆ๋งŒ ํ˜ธ์ถœ๋œ๋‹ค.
call AppConfig.memberService
call AppConfig.memberRepository
call AppConfig.orderService

 

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

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

 

๋ชจ๋“  ๋น„๋ฐ€์€ @Configuration์„ ์‚ฌ์šฉํ•œ AppConfig์— ์žˆ๋‹ค. ์‚ฌ์‹ค ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ๊ตฌํ˜„์ฒด(AnnotationConfigApplicationContext)๋ฅผ ๋งŒ๋“ค ๋•Œ ํŒŒ๋ผ๋ฉ”ํƒ€๋กœ ๋„˜๊ธด ๊ฐ’์€ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋œ๋‹ค. ์ฆ‰ AppConfig ๊ฐ€ ์Šคํ”„๋ง ๋นˆ์ด ๋œ๋‹ค๋Š” ๋ง์ด๋‹ค.

@Test
void configurationDeep(){
    ApplicationContext ac=new
    AnnotationConfigApplicationContext(AppConfig.class);
    
    // AppConfig๋„ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋œ๋‹ค.
    AppConfig bean=ac.getBean(AppConfig.class);

    // ์ˆœ์ˆ˜ํ•œ ํด๋ž˜์Šค Bean ์˜ ์ถœ๋ ฅ = class hello.core.AppConfig
    System.out.println("bean = "+bean.getClass());
    // ์‹ค์ œ ์ฝ˜์†”์ฐฝ ์ถœ๋ ฅ: bean = class hello.core.AppConfig$$EnhancerBySpringCGLIB$$bd479d70
    
}

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

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

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

 

# @Configuration์„ ์ ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด์š”?

๋ชจ๋“  ๋น„๋ฐ€์€ @Configuration์„ ์‚ฌ์šฉํ•œ AppConfig ์— ์žˆ๋‹ค.

์Šคํ”„๋ง์˜ @Configuration ์„ค์ •์€ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” CGLIB ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹ฑ๊ธ€ํ†ค์„ ๋ณด์žฅํ•œ๋‹ค. ๋งŒ์•ฝ ์ด๋ฅผ ์ ์šฉํ•˜์ง€ ์•Š๊ณ , @Bean๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

// ์–ด๋…ธํ…Œ์ด์…˜์„ ์ฃผ์„์ฒ˜๋ฆฌํ•˜์˜€์Œ.
// @Configuration
public class AppConfig {
	...
}
/* AppConfig๋ฅผ ์ฝ˜์†”์— ์ถœ๋ ฅํ•œ ๋ชจ์Šต.
  AppConfig bean=ac.getBean(AppConfig.class);
  System.out.println("bean = "+bean.getClass());
*/
bean = class hello.core.AppConfig

CGLIB ๊ธฐ์ˆ ์ด ์—†์ด ์ˆœ์ˆ˜ํ•œ AppConfig๋กœ ์Šคํ”„๋ง ๋นˆ์— ๋“ฑ๋ก๋œ๋‹ค. ์‹ค์ œ๋กœ ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๊ฒŒ๋˜๋ฉด ์ผ๋ฐ˜ ์ž๋ฐ”์ฝ”๋“œ์™€ ๋‹ค๋ฅธ๊ฒŒ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ์œ„์—์„œ ๋งํ•œ ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด๋ฅผ ์œ ์ง€ํ•˜์ง€ ๋ชปํ•œ๋‹ค. ์œ„์˜ ์˜ˆ์ œ๋ฅผ ๋‹ค์‹œ ๋Œ๋ ค๋ณด๋ฉด memberRepository๋ฅผ ํ˜ธ์ถœํ•œ ๋งŒํผ ๊ฐ์ฒด๋ฅผ ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

call AppConfig.memberService
call AppConfig.memberRepository // @Bean ์ตœ์ดˆ ๋“ฑ๋ก
call AppConfig.orderService
call AppConfig.memberRepository // OrderService -> memberRepository()
call AppConfig.memberRepository // MemberReposiotry -> memberRepository()

๋‹น์—ฐํ•˜๊ฒŒ๋„ ์ด๋ ‡๊ฒŒ Bean์„ ๋ฎ์–ด์”Œ์šฐ๊ฒŒ๋˜๋ฉด ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ฐ™์€์ง€ ํ…Œ์ŠคํŠธํ•˜๋Š” ์ฝ”๋“œ๋Š” ์ •์ƒ์ž‘๋™ ํ•˜์ง€์•Š๋Š”๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ฐ๊ฐ์˜ ์„œ๋น„์Šค๋งˆ๋‹ค ๋‹ค๋ฅธ memberRepository() ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

 


# ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋งŒ๋“ค๋ฉด ์ข‹์„๊นŒ์š”?

์•„๋‹ˆ๋‹ค. ์žฌ์‚ฌ์šฉ ํ•  ์ผ์ด ๋”ฑํžˆ ์—†๋Š” ๊ฐ์ฒด๋‚˜ ์Šคํ”„๋ง์˜ ์˜์กด์„ฑ ์ฃผ์ž…์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋ฉด, ๊ทธ๋ƒฅ new๋กœ ์ƒ์„ฑํ•ด๋„ ๋œ๋‹ค.

์Šคํ”„๋ง์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฐ€์ด๋“œ๋ผ์ธ์„ ์ œ๊ณตํ•œ๋‹ค.

 

๐Ÿ‘ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์€ ๊ฒฝ์šฐ

  • ๋‹ค๋ฅธ ๊ฐ์ฒด์˜ ์˜์กด์„ฑ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ
  • ๋‹ค๋ฅธ ์Šคํ”„๋ง ๋นˆ์˜ ์˜์กด์„ฑ์œผ๋กœ ์ฃผ์ž… ๋˜๋Š” ๊ฒฝ์šฐ
  • ์Šคํ”„๋ง์˜ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ (ํŠธ๋žœ์žญ์…˜, ์ธํ„ฐ์…‰ํ„ฐ, ํ”„๋ก์‹œ, SpringDataJpa๋“ฑ)


๐Ÿ‘Ž ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๊ตณ์ด ๋“ฑ๋กํ•  ํ•„์š” ์—†๋Š” ๊ฒฝ์šฐ

  • ์œ„์™€ ๋ฐ˜๋Œ€๋กœ ๋”ฑํžˆ ์ฃผ์ž…๋ฐ›๊ฑฐ๋‚˜ ์ฃผ์ž…ํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ
  • Spring์˜ ๊ธฐ๋Šฅ์ด ๋”ฑํžˆ ํ•„์š”์—†๋Š” ๊ฒฝ์šฐ
  • ๋Œ€ํ‘œ์ ์œผ๋กœ Entity, DTO, Value Object ๋“ฑ

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

 

 

# ๊ฒฐ๋ก 

์‚ฌ์‹ค ์–ด๋ ต๊ฒŒ ์„ค๋ช…ํ–ˆ์ง€๋งŒ, ๊ฒฐ๋ก ์€ ์Šคํ”„๋ง ์„ค์ • ์ •๋ณด๋Š” ํ•ญ์ƒ @Configuration์„ ์‚ฌ์šฉํ•˜์ž๋ผ๋Š” ๋ง์ด๋‹ค. ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํ”„๋ง์—์„œ ์–ด๋–ค ๋ฐฉ๋ฒ•์„ ์จ์„œ๋ผ๋„ ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด๋ฅผ ์œ ์ง€ํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.

 

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

JiwonDev

JiwonDev

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