Backend/๐ŸŒฑ Spring

[Spring]์˜์กด๊ด€๊ณ„ ์ฃผ์ž…(DI)

HS0601 2025. 7. 28. 10:57
์˜์กด๊ด€๊ณ„ ์ฃผ์ž…(DI)์ด๋ž€?
์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ํ•„์š”๋กœ ํ• ๋•Œ, ๊ทธ๊ฑธ ์ง์ ‘ newํ•˜์ง€ ์•ˆ๊ณ  ์Šคํ”„๋ง์ด ๋Œ€์‹  ๋„ฃ์–ด์ฃผ๋Š” ๊ฒƒ.
์‰ฝ๊ฒŒ ๋งํ•ด, ํ•„์š”ํ•œ ๊ฐ์ฒด๋ฅผ ๋‚ด๊ฐ€ ๋งŒ๋“ค์ง€ ์•Š๊ณ , ์Šคํ”„๋ง์ด ๋Œ€์‹  ๋งŒ๋“ค์–ด์„œ ๋„ฃ์–ด์ฃผ๋Š” ๊ฒƒ
๊ทธ๋ฆฌ๊ณ  ๋ฐฉ๋ฒ• ์ค‘ ์ƒ์„ฑ์ž ์ฃผ์ž…์ด ๊ฐ€์žฅ ์•ˆ์ •์ ์ด๊ณ  ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ์‹์ด๋‹ค.


Bean๊ณผ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…(DI)์˜ ๊ด€๊ณ„
Bean์€ ์Šคํ”„๋ง์ด ๋Œ€์‹  ๋งŒ๋“ค์–ด์„œ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ์ฒด๊ณ 
์˜์กด๊ด€๊ณ„์ฃผ์ž…์€ ๊ทธ Bean์„ ํ•„์š”ํ•œ ๊ณณ์—์„œ ์ž๋™์œผ๋กœ ๋„ฃ์–ด์ฃผ๋Š” ํ–‰์œ„๋ผ๊ณ  ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค.

 

 

๋ฆฌ์•กํŠธ๋กœ ๋น„์œ ํ•˜์ž๋ฉด,

// ์ง์ ‘ new ํ•˜๋Š” ๊ตฌ์กฐ (์˜์กด๊ด€๊ณ„ ์ฃผ์ž… x)
function Profile() {
  const user = new User();  // ๋‚ด๊ฐ€ ์ง์ ‘ ๋งŒ๋“ค์—ˆ์Œ
  return <div>{user.name}</div>;
}


// ์˜์กด๊ด€๊ณ„ ์ฃผ์ž… ๊ตฌ์กฐ (Context ๋˜๋Š” props๋กœ ์ „๋‹ฌ๋ฐ›์Œ)
function Profile({ user }) {
  return <div>{user.name}</div>;
}

user๋ฅผ ์ง์ ‘ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ๋ฐ–์—์„œ ๋„ฃ์–ด์ฃผ๋Š”๋ฐ, ์ด๊ฒŒ ๋ฐ”๋กœ ์˜์กด์„ฑ ์ฃผ์ž….

 

 

 

์Šคํ”„๋ง์—์„œ๋Š” ๋ฐฉ๋ฒ•์ด 4๊ฐœ์ธ๋ฐ, 3๊ฐœ๋งŒ ๊ธฐ์–ตํ•˜๋ฉด ๋œ๋‹ค.

1. ์ƒ์„ฑ์ž ์ฃผ์ž…

- ๊ฐ€์žฅ ์•ˆ์ •ํ•˜๊ณ  ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ์‹(๋ถˆ๋ณ€+ํ•„์ˆ˜)

2. ํ•„๋“œ ์ฃผ์ž…

- ํ…Œ์ŠคํŠธ ์–ด๋ ค์›€, ์™ธ๋ถ€์—์„œ ๋ฐ”๊พธ๊ธฐ ์–ด๋ ค์›€(์ง€์–‘)

3.  Setter์ฃผ์ž…

- ํ•„์š”ํ•  ๋•Œ๋งŒ, ์„ ํƒ์‚ฌํ•ญ์ผ ๋•Œ ์‚ฌ์šฉ

 

 

 

์™œ ์ง์ ‘ new ํ•˜์ง€ ์•Š๊ณ  ์˜์กด์„ฑ ์ฃผ์ž…(DI)์„ ์“ธ๊นŒ?

์ง์ ‘ new ํ•˜๋ฉด ๊ทธ ์•ˆ์—์„œ ์–ด๋–ค ๊ฑธ ์“ฐ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์ง€๋งŒ, ์žฌ์‚ฌ์šฉ๋„ ์–ด๋ ต๊ณ  ํ…Œ์ŠคํŠธ๋„ ํž˜๋“ค๊ณ  ๋ณ€๊ฒฝ๋„ ์–ด๋ ค์›€

 

๋ฐ˜๋ฉด, ์˜์กด๊ด€๊ณ„๋ฅผ ๋ฐ”๊นฅ์—์„œ ๋„ฃ์–ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์—

ํ…Œ์ŠคํŠธํ•  ๋•Œ๋„ ์‰ฝ๊ฒŒ ๊ฐ€์งœ๊ฐ์ฒด๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ๊ณ 

์ฝ”๋“œ ์ˆ˜์ • ์—†์ด ์ƒˆ๋กœ์šด ๊ตฌํ˜„์ฒด๋กœ ๊ฐˆ์•„๋ผ์šธ ์ˆ˜ ์žˆ๊ณ 

๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜์ง€ ์•Š์œผ๋‹ˆ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ํŽธํ•ด์ง„๋‹ค.

@Component
public class NotificationService {
    public void send() {
        System.out.println("์•Œ๋ฆผ ์ „์†ก ์™„๋ฃŒ!");
    }
}
@Component
@RequiredArgsConstructor
public class UserService {

    private final NotificationService notificationService;

    public void process() {
        // ์ด ๊ฐ์ฒด๋Š” ๋‚ด๊ฐ€ new๋กœ ๋งŒ๋“  ๊ฒŒ ์•„๋‹˜
        // ์Šคํ”„๋ง์ด ๋Œ€์‹  ๋„ฃ์–ด์ค€ Bean์ž„
        notificationService.send();
    }
}
@SpringBootApplication
public class MainApp {
    public static void main(String[] args) {
        var context = SpringApplication.run(MainApp.class, args);

        // ์Šคํ”„๋ง์ด ๋งŒ๋“  UserService๋ฅผ ๊ฐ€์ ธ์™€์„œ ์‹คํ–‰
        UserService userService = context.getBean(UserService.class);
        userService.process();
    }
}

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ํฌ์ธํŠธ๋Š” UserService๊ฐ€ NotificationService๋ฅผ ์ง์ ‘ newํ•˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฒƒ.

๋Œ€์‹  ์Šคํ”„๋ง์ด ์ปจํ…Œ์ด๋„ˆ์— NotificationService๋ฅผ ๋“ฑ๋กํ•ด ๋‘๊ณ  ํ•„์š”ํ•œ ๊ณณ์— ์ž๋™์œผ๋กœ ๋„ฃ์–ด์คŒ<= ์ด๊ฒŒ DI

 

 

์ƒ์„ฑ์ž ์ฃผ์ž…์ด๋ž€?
@Component
public class MyApp {

    private final MyService myService;

    @Autowired // ์Šคํ”„๋ง์ด ์ด ์ƒ์„ฑ์ž์— ์ฃผ์ž…ํ•ด์คŒ
    public MyApp(MyService myService) {
        this.myService = myService;
    }

    public void run() {
        myService.doSomething();
    }
}

์Šคํ”„๋ง์ด ์•ฑ ์‹คํ–‰ํ•  ๋•Œ, MyApp ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

๊ทผ๋ฐ ์ƒ์„ฑ์ž ๋ณด๋‹ˆ๊นŒ MyService๋ฅผ ์ค˜์•ผ ๋งŒ๋“ค์–ด์งˆ ์ˆ˜ ์žˆ์Œ

๊ทธ๋ž˜์„œ ์Šคํ”„๋ง์ด ์ปจํ…Œ์ด๋„ˆ์—์„œ MyService ๋นˆ์„ ๊บผ๋‚ด์„œ ๋„ฃ์–ด์ค€๋‹ค.

์ด๋ ‡๊ฒŒ ์ž๋™์œผ๋กœ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ๊ฒŒ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…!!!

 

React๋กœ ๋น„์œ ํ•ด๋ณด์ž๋ฉด,

function App() {
  const user = new User(); // ์Šคํ”„๋ง์ด ๋Œ€์‹  ๋งŒ๋“ค์–ด์ค€ ๊ฐ์ฒด๋ผ๊ณ  ์ƒ๊ฐ!
  return <Profile user={user} />; // ์˜์กด์„ฑ ์ฃผ์ž…!
}

function Profile({ user }) {
  return <div>{user.name}</div>;
}

 

 

 

 

์ƒ์„ฑ์ž ์ฃผ์ž…์ด ์ข‹์€ ์ด์œ 

 

  • ๋ถˆ๋ณ€์„ฑ
    • final๋กœ ๋งŒ๋“ค์–ด์„œ ๋‚˜์ค‘์— ์‹ค์ˆ˜๋กœ ๋ฐ”๋€” ์ผ ์—†์Œ
  • ํ•„์ˆ˜์„ฑ
    • ๊ผญ ํ•„์š”ํ•œ ์• ๋А ์ƒ์„ฑ์ž์—์„œ ๋ฐ”๋กœ ๋ฐ›์•„์•ผํ•จ
  • ํ…Œ์ŠคํŠธ ์‰ฌ์›€
    • new๋กœ ๋งŒ๋“ค ๋•Œ ๋ฐ”๋กœ ๋„ฃ์„ ์ˆ˜ ์žˆ์–ด์„œ ์ˆœ์ˆ˜ ์ž๋ฐ”์—์„œ๋„ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅํ•จ
  • ์ปดํŒŒ์ผ ํƒ€์ž„ ์ฒดํฌ
    • ์—†์œผ๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ, NPE์•ˆํ„ฐ์ง

 

๋‹ค๋ฅธ ๋ฐฉ์‹๋„ ์งš๊ณ  ๋„˜์–ด๊ฐ€ ๋ณด์ž,

 

 

ํ•„๋“œ ์ฃผ์ž… (์ง€์–‘)
@Component
public class UserService {
    @Autowired
    private NotificationService notificationService;
}

์ฝ”๋“œ๋Š” ์งง์ง€๋งŒ ๋‹จ์ ์ด ๋งŽ๋‹ค.

ํ…Œ์ŠคํŠธ ํ•  ๋•Œ ์ง์ ‘ ๊ฐ’์„ ๋„ฃ์„ ์ˆ˜ ์—†์Œ-> ํ…Œ์ŠคํŠธ ์–ด๋ ค์›€

final์„ ๋ชป ์Šค๋‹ˆ๊นŒ ์‹ค์ˆ˜๋กœ ๋‹ค๋ฅธ ๊ฐ’์œผ๋กœ ๋ฐ”๋€” ์ˆ˜๋„ ์žˆ์Œ

์Šคํ”„๋ง ์—†์ด ์‹คํ–‰ํ•˜๋ฉด ๋™์ž‘ ์•ˆ๋จ

๋”ฐ๋ผ์„œ ์‹ค๋ฌด์—์„œ ํ…Œ์ŠคํŠธ๋‚˜ ์„ค์ • ์ฝ”๋“œ ์ผ๋ถ€์—๋งŒ ์ œํ•œ์ ์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

 

 

Setter ์ฃผ์ž… (์„ ํƒ์ ์ผ ๋•Œ ์‚ฌ์šฉ)
@Component
public class UserService {
    private NotificationService notificationService;

    @Autowired
    public void setNotificationService(NotificationService notificationService) {
        this.notificationService = notificationService;
    }
}

์„ ํƒ์ ์ธ ์˜์กด์„ฑ ์ฃผ์ž…์ด ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. -> ๊ผญ ์—†์–ด๋„ ๋˜๋Š” ๋ถ€๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์ผ ๊ฒฝ์šฐ

๊ฐ์ฒด ์ƒ์„ฑ ํ›„์— ๋ฐ”๊ฟ” ๋ผ์šฐ๊ธฐ๋„ ๊ฐ€๋Šฅ-> ์‹ค๋ฌด์—์„œ๋Š” ๋“œ๋ฌผ์ง€๋งŒ ์œ ์—ฐํ•œ๊ฒŒ ์„ค๊ณ„ํ•  ๋•Œ ์ข…์ข…์‚ฌ์šฉ๋จ

 

 

@RequiredArgsConstructor๋Š” ๋ญ์ž„?

 

Lombok์ด ์ž๋™์œผ๋กœ ์ด ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.

@RequiredArgsConstructor
public class MyApp {
    private final MyService myService;

    // ์ž๋™์œผ๋กœ ์ด ์ƒ์„ฑ์ž๊ฐ€ ๋งŒ๋“ค์–ด์ง:
    // public MyApp(MyService myService) { this.myService = myService; }
}

final ๋ถ™์€ ํ•„๋“œ๋“ค์„ ๋ชจ์•„์„œ ์ƒ์„ฑ์ž๋ฅผ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์ค€๋‹ค

์Šคํ”„๋ง์ด ๊ฑฐ๊ธฐ๋‹ค๊ฐ€ ์ž๋™์œผ๋กœ @Autowired๋กœ ์ฃผ์ž…ํ•จ.

 

 

 

 

 

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

[Spring] filter์‹ค์Šต๊นŒ์ง€ ์ง„ํ–‰ํ•œ ํ›„ ์ดํ•ดํ•œ ๋‚ด์šฉ ์ •๋ฆฌ  (1) 2025.07.29
[Spring] Bean Validation  (5) 2025.07.28
[Spring]Spring Bean  (2) 2025.07.28
[Spring] Layered Architecture  (3) 2025.07.26
[Spring] Mapping  (1) 2025.07.23