1. Dependency Injection

1-1. Dependency Injection์ด๋ž€?

1-1-1. Dependency Injection

<aside> ๐Ÿ’ก Dependency Injection(์˜์กด์„ฑ ์ฃผ์ž…, ์ดํ•˜ DI)์€ ๊ฐ์ฒด ๊ฐ„์˜ ์˜์กด ๊ด€๊ณ„๋ฅผ ๋นˆ ์„ค์ • ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ž๋™์ ์œผ๋กœ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถœ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๋กœ ์ธํ•ด ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ์œ ์—ฐ์„ฑ์ด ์ฆ๊ฐ€ํ•œ๋‹ค.

</aside>

1-1-2. ์˜์กด ๊ด€๊ณ„์™€ ๊ฒฐํ•ฉ๋„

public class A {
	
	private B b = new B();

}

public class B {

}

class A ๊ฐ€ class B ๋ฅผ ํ•„๋“œ๋กœ ๊ฐ€์งˆ ๋•Œ A๋Š” B์— ์˜์กดํ•˜๊ฒŒ ๋œ๋‹ค.

public class A {

	/* ์ปดํŒŒ์ผ ์—๋Ÿฌ ๋ฐœ์ƒ */
	private B b = new B();

}

/* ํด๋ž˜์Šค๋ช…์ด B์—์„œ NewB๋กœ ๋ณ€๊ฒฝ */
public class NewB {
	
}

์˜์กด์„ฑ์ด ๊ฐ•ํ•˜๋‹ค๋Š” ๊ฒƒ์€ ํ•œ ๊ฐ์ฒด๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์ด์— ์˜์กดํ•˜๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค๋„ ํ•จ๊ป˜ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. B๊ฐ€ NewB ๋กœ ๋ณ€๊ฒฝ๋˜๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ํ•„๋“œ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” A ๋„ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•  ๊ฒƒ์ด๋‹ค. ์ด์ฒ˜๋Ÿผ ๊ฐ์ฒด ๊ฐ„์˜ ์˜์กด ๊ด€๊ณ„๊ฐ€ ๊ฐ•ํ•˜๊ฒŒ ๋ฌถ์—ฌ์žˆ์„ ๋•Œ ๊ฒฐํ•ฉ๋„ ๊ฐ€ ๋†’๋‹ค๊ณ  ํ‘œํ˜„ํ•œ๋‹ค. ์ด๋กœ ์ธํ•ด ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ์œ ์—ฐ์„ฑ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ๋‹ค.

public class A {

	/* ์ƒ์œ„ ํƒ€์ž…์„ ํ•„๋“œ๋กœ ์„ค์ • */
	private B b;

	/* ์ง์ ‘ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ ๋ฐ›์Œ */
	public A(B b) {
		this.b = b;
	}

}

/* ์ƒ์œ„ ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•  ์ธํ„ฐํŽ˜์ด์Šค */
public interface B {

}

/* ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„ ํด๋ž˜์Šค */
public class NewB implements B {

}
public class A {

	/* ์ƒ์œ„ ํƒ€์ž…์„ ํ•„๋“œ๋กœ ์„ค์ • */
	private B b;

	/* ์ง์ ‘ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ ๋ฐ›์Œ */
	public A(B b) {
		this.b = b;
	}

}

/* ์ƒ์œ„ ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•  ์ธํ„ฐํŽ˜์ด์Šค */
public interface B {

}

/* ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„ ํด๋ž˜์Šค */
public class NewB implements B {

}

์ด์ „์˜ ์ฝ”๋“œ์™€ ๋น„๊ตํ•˜๋ฉด NewB ๋ผ๋Š” ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„์ฒด์˜ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  B ๋ผ๋Š” ์ƒ์œ„ ์ธํ„ฐํŽ˜์ด์Šค ํƒ€์ž…์œผ๋กœ ํ•„๋“œ๋ฅผ ์„ ์–ธํ–ˆ๋‹ค. ๋˜ํ•œ ์ง์ ‘ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ตฌ๋ฌธ๋„ ์—†์–ด์กŒ๊ณ  ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ ๋ฐ›๋„๋ก ํ–ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋ณ€๊ฒฝํ•˜๋ฉด ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ตฌํ˜„์ฒด๊ฐ€ NewB ์—์„œ ๋˜ ๋‹ค๋ฅธ ํƒ€์ž…์œผ๋กœ ๋ณ€๊ฒฝ ๋˜๋”๋ผ๋„ A ์˜ ์ฝ”๋“œ๋Š” ๋ณ€๊ฒฝ ๋  ํ•„์š”๊ฐ€ ์—†๋‹ค. ์˜์กด ๊ด€๊ณ„๊ฐ€ ๋А์Šจํ•ด์ง€๊ณ  ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ์•„์กŒ๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

2. DI ๋ฐฉ๋ฒ• ์•Œ์•„๋ณด๊ธฐ

์•„๋ž˜ ์ฝ”๋“œ๋Š” ํ…Œ์ŠคํŠธ์— ๊ณตํ†ต์ ์œผ๋กœ ์‚ฌ์šฉ ํ•  Account, PersonalAccount, MemberDTO ํด๋ž˜์Šค์ด๋‹ค.

  1. Account

    public interface Account {
    
        /* ์ž”์•ก ์กฐํšŒ */
        String getBalance();
    
        /* ์ž…๊ธˆ */
        String deposit(int money);
    
        /* ์ถœ๊ธˆ */
        String withDraw(int money);
    
    }
    
  2. PersonalAccount

    @Data
    public class PersonalAccount implements Account {
    
        private final int bankCode;       //์€ํ–‰์ฝ”๋“œ
        private final String accNo;       //๊ณ„์ขŒ๋ฒˆํ˜ธ
        private int balance;              //์ž”์•ก
    
        @Override
        public String getBalance() {
    
            return this.accNo + " ๊ณ„์ขŒ์˜ ํ˜„์žฌ ์ž”์•ก์€ " + this.balance + "์› ์ž…๋‹ˆ๋‹ค.";
        }
    
        @Override
        public String deposit(int money) {
    
            String str = "";
    
            if(money >= 0) {
                this.balance += money;
                str = money + "์›์ด ์ž…๊ธˆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.";
            } else {
                str = "๊ธˆ์•ก์„ ์ž˜๋ชป ์ž…๋ ฅํ•˜์…จ์Šต๋‹ˆ๋‹ค.";
            }
    
            return str;
        }
    
        @Override
        public String withDraw(int money) {
    
            String str = "";
    
            if(this.balance >= money) {
                this.balance -= money;
                str = money + "์›์ด ์ถœ๊ธˆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.";
            } else {
                str = "์ž”์•ก์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค. ์ž”์•ก์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”.";
            }
    
            return str;
        }
    
    }
    
  3. MemberDTO

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class MemberDTO {
    	
        private int sequence;                 //ํšŒ์›๋ฒˆํ˜ธ
        private String name;                  //์ด๋ฆ„
        private String phone;                 //ํœด๋Œ€ํฐ๋ฒˆํ˜ธ
        private String email;                 //์ด๋ฉ”์ผ
        private Account personalAccount;      //๊ฐœ์ธ๊ณ„์ขŒ
    
    }
    
    @Bean
    public Account accountGenerator() {
    
    		return new PersonalAccount(20, "110-234-567890");
    }
    
    @Bean
    public MemberDTO memberGenerator() {
    
    		/* MemberDTO ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด Account๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๋ฆฌํ„ด ๊ฐ’์„ ์ „๋‹ฌํ•˜์—ฌ bean์„ ์กฐ๋ฆฝํ•  ์ˆ˜ ์žˆ๋‹ค. */
    		return new MemberDTO(1, "ํ™๊ธธ๋™", "010-1234-5678", "[email protected]", accountGenerator());
    }
    

โ‡’ Account(๊ณ„์ขŒ) ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ PersonalAccount(๊ฐœ์ธ๊ณ„์ขŒ) ํด๋ž˜์Šค๊ฐ€ ์žˆ๊ณ  MemberDTO ๋Š” Account ํƒ€์ž…์„ ํ•„๋“œ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. (MemberDTO ๋Š” Account ํƒ€์ž…์— ์˜์กดํ•œ๋‹ค.)

2-1. XML Configuration

2-1-1. ์ƒ์„ฑ์ž(Constructor) ์ฃผ์ž