[๐Ÿ’ก] ์˜์กด์„ฑ ์ฃผ์ž…(DI)์— ๊ด€ํ•˜์—ฌ..(_ _)

์„œ์€๊ฒฝยท2026๋…„ 3์›” 25์ผ

Spring

๋ชฉ๋ก ๋ณด๊ธฐ
44/44

ํ•  ๋•Œ๋งˆ๋‹ค ํ—ท๊ฐˆ๋ฆฌ๊ณ 
ํ•  ๋•Œ๋งˆ๋‹ค ๊นŒ๋จน๋Š”
spring boot ๊ธฐ๋ณธ ๊ฐœ๋… ์›๋ฆฌ ๊ธฐํƒ€ ๋“ฑ๋“ฑ ..

์™œ์“ฐ๋Š”์ง„ ์•Œ๊ณ  ์“ฐ์ž !!!

์˜์กด์„ฑ ์ฃผ์ž…์—๋Š” ์ด ์„ธ๊ฐ€์ง€ ๋ฐฉ์‹์ด ์žˆ๋‹ค

  1. ํ•„๋“œ ์ฃผ์ž… (@Autotiwerd) โ†’ ๋‚ด๊ฐ€ ๊ฐ€์žฅ ๋งŽ์ด ์ผ๋˜ ๋ฐฉ์‹
@Service
public class MyService {
	@Autowired
    private TestService testService;
}
  1. ์ƒ์„ฑ์ž ์ฃผ์ž…(@RequiredArgsConstructor) โ†’ ์ข…์ข… ์”€
@Service
@RequiredArgsConstructor
public class MyService {
    private final TestService testService;
}
  1. ์ˆ˜์ •์ž ์ฃผ์ž…(setter)
@Service
public class MyService {
    private TestService testService;
    
    @Autowired
    public void setTestService(TestService testService) {
    	this.testService = testService;
    }
}

1.ํ•„๋“œ ์ฃผ์ž… ์€ ๊ฐ์ฒด๊ฐ€ ๋จผ์ € ๋งŒ๋“ค์–ด์ง€๊ณ  ๋‚˜์ค‘์— ํ•„๋“œ๊ฐ€ ์ฑ„์›Œ์ง„๋‹ค. private ์ธ๋ฐ๋„ ๋ฆฌํ”Œ๋ ‰์…˜์œผ๋กœ ๋šซ๊ณ  ๋“ค์–ด๊ฐ„๋‹ค๊ณ  ํ•œ๋‹ค.

Spring ์ปจํ…Œ์ด๋„ˆ
  โ†’ ๊ฐ์ฒด ์ƒ์„ฑ (๊ธฐ๋ณธ ์ƒ์„ฑ์ž)
  โ†’ ๋ฆฌํ”Œ๋ ‰์…˜์œผ๋กœ private ํ•„๋“œ์— ๊ฐ•์ œ ์ฃผ์ž…
  โ†’ ์™„์„ฑ

2.์ƒ์„ฑ์ž ์ฃผ์ž… ์€ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•จ๊ณผ ๋™์‹œ์— ์ฃผ์ž…๋œ๋‹ค. final์ด๋ผ ์ดํ›„ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š”๋‹ค.

@RequiredArgsConstructor
public class MyService {
    private final FileService fileService;
}

// Lombok์ด ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ž๋™ ์ƒ์„ฑ
public MyService(TestService testService) {
    this.testService = testService;
}

Spring ์ปจํ…Œ์ด๋„ˆ
  โ†’ TestService ๋จผ์ € ์ค€๋น„
  โ†’ ์ƒ์„ฑ์ž ํ˜ธ์ถœํ•˜๋ฉด์„œ ์ฃผ์ž…
  โ†’ ๊ฐ์ฒด ์™„์„ฑ

Autowired๊ฐ€ ํŽธํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ด์„œ ์ž์ฃผ ์ผ์—ˆ๋Š”๋ฐ
spring ๊ณต์‹๋ฌธ์„œ, InteliJ๋„ ์ƒ์„ฑ์ž ์ฃผ์ž… ์„ ์“ฐ๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

์™œ ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ๊ถŒ์žฅํ•˜๋Š”๊ฐ€ why ??? ๐Ÿ™„

final๋กœ ๋ถˆ๋ณ€์„ฑ ๋ณด์žฅ

์ˆœํ™˜์ฐธ์กฐ๋ฅผ ์ปดํŒŒ์ผ/์‹œ์ž‘ ์‹œ์ ์— ์žก์Œ

// A๊ฐ€ B๋ฅผ ์ฐธ์กฐ, B๊ฐ€ A๋ฅผ ์ฐธ์กฐ
@Service
public class A {
    @Autowired B b; // ํ•„๋“œ ์ฃผ์ž… โ†’ ๋Ÿฐํƒ€์ž„์— ์•ฑ ๋œจ๊ณ  ๋‚˜์„œ์•ผ ์˜ค๋ฅ˜ ๋ฐœ๊ฒฌ
}

@Service
public class B {
    @Autowired A a;
}

// ์ƒ์„ฑ์ž ์ฃผ์ž… โ†’ ์•ฑ ์‹œ์ž‘ํ•  ๋•Œ ๋ฐ”๋กœ ์˜ค๋ฅ˜ ๋ฐœ๊ฒฌ (Spring Boot 2.6+)
// BeanCurrentlyInCreationException ์ฆ‰์‹œ ๋ฐœ์ƒ

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ์ด ํ›จ์”ฌ ์‰ฌ์›€

// ํ•„๋“œ ์ฃผ์ž… - ํ…Œ์ŠคํŠธํ•  ๋•Œ Mock ์ฃผ์ž…์ด ์–ด๋ ค์›€
public class MyServiceTest {
    // fileService๋ฅผ ์–ด๋–ป๊ฒŒ ๋„ฃ์ง€..? @Autowired๊ฐ€ ์—†์œผ๋ฉด null
    MyService myService = new MyService();
}

// ์ƒ์„ฑ์ž ์ฃผ์ž… - ํ…Œ์ŠคํŠธํ•  ๋•Œ ๊ทธ๋ƒฅ ๋„ฃ์œผ๋ฉด ๋จ
public class MyServiceTest {
    FileService mockFileService = mock(FileService.class);
    MyService myService = new MyService(mockFileService); // ๊น”๋”
}

๋‚˜๋Š” ์™œ ํ•„๋“œ์ฃผ์ž…์„ ์ž์ฃผ ์ผ๋Š”๊ฐ€ !??!?!?!?

์‚ฌ์‹ค ์ž˜ ๋ชฐ๋ผ์„œ๊ฐ€ ๊ฐ€์žฅ ํฌ๋‹ค
@RequiredArgsConstructor๋ฅผ ๋ฌด๋ถ„๋ณ„ํ•˜๊ฒŒ ์“ฐ๋ฉด ์•ˆ๋œ๋‹ค๋Š” ๊ฑธ ์–ด๋””์„œ ๋ดค๋˜ ๊ฒƒ ๊ฐ™์€๋ฐ(์•„๋งˆ Entity์— ์“ฐ์ง€ ๋ง๋ž€ ํฌ์ŠคํŠธ๋ฅผ ๋ดค๋˜ ๋“ฏ...) ๋„ˆ๋ฌด ์–ด๊นจ๋„ˆ๋จธ๋กœ ๋ด์„œ ๊ทธ๋ƒฅ ์ฝ”๋“œ๋„ ๊ฐ„๊ฒฐํ•œ Autowired๋ฅผ ์ผ๋˜ ๊ฒƒ ๊ฐ™๋‹ค.

ํ•˜์ง€๋งŒ ๊ทธ๋ ‡๋‹ค๊ณ  ๋‹จ์ ์ด๋‚˜ ๋ฆฌ์Šคํฌ๊ฐ€ ์•„์˜ˆ ์—†๋Š” ๊ฒƒ๋„ ์•„๋‹ˆ๋‹ˆ ์ฐธ๊ณ ํ•˜์—ฌ ์“ฐ์ž!

// @AllArgsConstructor โ†’ ๋ชจ๋“  ํ•„๋“œ ์ƒ์„ฑ์ž
// @NoArgsConstructor  โ†’ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž
// @RequiredArgsConstructor โ†’ final or @NonNull ํ•„๋“œ๋งŒ

1.์˜์กด์„ฑ์ด ๋„ˆ๋ฌด ๋งŽ์•„์ง

@RequiredArgsConstructor
public class MyController {
    private final ServiceA a;
    private final ServiceB b;
    private final ServiceC c;
    private final ServiceD d;
    private final ServiceE e;
    // final๋งŒ ๋ถ™์ด๋ฉด ์ž๋™์œผ๋กœ ์ƒ์„ฑ์ž์— ์ถ”๊ฐ€๋˜๋‹ˆ๊นŒ
    // ํด๋ž˜์Šค๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์€ ์ฑ…์ž„์„ ๊ฐ–๊ณ  ์žˆ๋‹ค๋Š” ๊ฑธ ๋ˆˆ์น˜์ฑ„๊ธฐ ์–ด๋ ค์›€
}

2.์ƒ์„ฑ์ž ์ˆœ์„œ ์˜์กด ๋ฌธ์ œ

@RequiredArgsConstructor
public class MyService {
    private final AService aService;
    private final BService bService;
}

// ์ƒ์„ฑ์ž ์ˆœ์„œ๊ฐ€ ํ•„๋“œ ์„ ์–ธ ์ˆœ์„œ๋กœ ๊ฒฐ์ •๋จ
// ๋‹ค๋ฅธ ๊ณณ์—์„œ ์ง์ ‘ ์ƒ์„ฑ์ž ํ˜ธ์ถœํ•  ๋•Œ ์ˆœ์„œ ํ—ท๊ฐˆ๋ฆด ์ˆ˜ ์žˆ์Œ
new MyService(aService, bService)  // โŒ ์ˆœ์„œ ๋ฐ”๊พธ๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ

3.JPA Entity ์— ์“ฐ๋ฉด ์œ„ํ—˜

@Entity
@RequiredArgsConstructor  // โŒ ์œ„ํ—˜
public class User {
    private final String name;
}
// JPA๋Š” ๊ธฐ๋ณธ ์ƒ์„ฑ์ž(NoArgsConstructor)๊ฐ€ ํ•„์š”ํ•œ๋ฐ
// final ํ•„๋“œ๋ฉด ๊ธฐ๋ณธ ์ƒ์„ฑ์ž ๋งŒ๋“ค ์ˆ˜ ์—†์–ด์„œ ์ถฉ๋Œ

controller๋‚˜ service์—” ์จ๋„ ๋˜์ง€๋งŒ ์˜์กด์„ฑ 5๊ฐœ ์ด์ƒ์ด ๋˜๋ฉด ํด๋ž˜์Šค ๋ถ„๋ฆฌ๋ฅผ ๊ณ ๋ คํ•˜๋Š” ์ชฝ์œผ๋กœ ํ•˜์—ฌ ์ž˜ ~~ ์‚ฌ์šฉํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค!

0๊ฐœ์˜ ๋Œ“๊ธ€