์คํ๋ง ํ๋ ์์ํฌ๋ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ํต์ฌ ์์น์ธ '์์กด์ฑ ์ญ์ ์์น'์ ๊ตฌํํ๋ ๋ฐ ์์ด์ ์์กด์ฑ ์ฃผ์ (Dependency Injection, DI)์ ์ค์ฌ์ผ๋ก ํ์ฉํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๊ณ , ์ ์ฐ์ฑ ๋ฐ ํ์ฅ์ฑ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. ์ฌ๊ธฐ์๋ ์คํ๋ง์์ ์ฃผ๋ก ์ฌ์ฉ๋๋ ์ธ ๊ฐ์ง ์์กด์ฑ ์ฃผ์ ๋ฐฉ์์ธ ์์ฑ์ ์ฃผ์ (Constructor Injection), ์์ ์ ์ฃผ์ (Setter Injection), ํ๋ ์ฃผ์ (Field Injection)์ ๋ํด ์์ธํ ์์๋ณด๊ณ , ๊ฐ ๋ฐฉ๋ฒ์ ํน์ง๊ณผ ์ฅ๋จ์ ์ ์ค๋ช ํ๊ฒ ์ต๋๋ค.
1. ์์ฑ์ ์ฃผ์ (Constructor Injection)
์์ฑ์๋ฅผ ํตํ ์์กด์ฑ ์ฃผ์ ์ ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋ ๋ชจ๋ ์์กด์ฑ์ด ์ถฉ์กฑ๋์ด์ผ ํจ์ ์๋ฏธํฉ๋๋ค. ์์ฑ์ ์ธ์๋ฅผ ํตํด ๋ชจ๋ ํ์ํ ์์กด์ฑ์ ์ ๊ณต๋ฐ๊ธฐ ๋๋ฌธ์, ๊ฐ์ฒด๊ฐ ์ฌ์ฉ๋๊ธฐ ์์ํ ๋ ์ด๋ฏธ ๋ชจ๋ ์์กด์ฑ์ด ์กด์ฌํ๊ฒ ๋ฉ๋๋ค. ์ด๋ ๊ฐ์ฒด๊ฐ ์ธ์ ๋ ์์ ํ๊ณ ์ผ๊ด๋ ์ํ๋ก ์๋๋ก ๋ณด์ฅํฉ๋๋ค. ๋ง์ฝ ์์กด์ฑ์ด ์ถฉ์กฑ๋์ง ์๋๋ค๋ฉด, ๊ฐ์ฒด๋ ์์ ์์ฑ๋์ง ์๊ธฐ ๋๋ฌธ์ ๋ฐํ์์ ๋ฐ์ํ ์ ์๋ ์์กด์ฑ ๊ด๋ จ ์ค๋ฅ๋ฅผ ์ฌ์ ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
์์ ์ฝ๋:
public class BookService {
private final BookRepository repository;
public BookService(BookRepository repository) {
this.repository = repository;
}
}
์์ ์ฝ๋ ์ธ๋ถ ๋์ ์์:
BookService
๊ฐ์ฒด ์์ฑ ์์ฒญ.BookRepository
์ธ์คํด์ค๊ฐ ํ์ํจ์ ์คํ๋ง์ด ์ธ์ง.BookRepository
์ธ์คํด์ค๋ฅผ ์์ฑํ๊ฑฐ๋ ๊ธฐ์กด์ ์กด์ฌํ๋ ๋น์ ์ฐพ์.BookRepository
์ธ์คํด์ค๋ฅผBookService
์์ฑ์์ ์ฃผ์ ํ๋ฉฐ ๊ฐ์ฒด ์์ฑ.- ์ ์ฒด ๋์ ์์:
- ์์กด์ฑ ํ์ธ: ์คํ๋ง ์ปจํ ์ด๋๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ ์ ์ ํ์ํ ์์กด์ฑ์ ๋จผ์ ํ์ธํฉ๋๋ค.
- ๋น ์์ฑ ๋ฐ ์ฃผ์ : ํ์ํ ์์กด์ฑ์ ์์ฑ์์ ์ธ์๋ก ์ ๋ฌํ๋ฉด์ ๊ฐ์ฒด(๋น)๋ฅผ ์์ฑํฉ๋๋ค.
์ฅ์ :
- ์์ ์ฑ: ์์กด์ฑ์ด ๋ช ์์ ์ด๋ฏ๋ก ์์ฑ์๋ฅผ ํตํด ์์ ์ ์ผ๋ก ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํํ ์ ์์ต๋๋ค.
- ๋ถ๋ณ์ฑ: ์์กด์ฑ ์ฃผ์ ํ์๋ ๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅํ์ฌ ๊ฐ์ฒด์ ์ํ๊ฐ ์ผ๊ด๋ฉ๋๋ค.
- ์ํ ์ฐธ์กฐ ์ค๋ฅ ํ์ธ ๊ฐ๋ฅ: ์๋ก ์์กดํ๋ ๊ฐ์ฒด ๊ฐ์ ์ํ ์ฐธ์กฐ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ, ์คํ๋ง์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์์ด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.(์์ฑ์๋ฅผ ํตํด ๋ชจ๋ ์์กด์ฑ์ด ์ฃผ์ ๋๊ธฐ ๋๋ฌธ์, ์ํ ์ฐธ์กฐ๊ฐ ์์ ๊ฒฝ์ฐ ์คํ๋ง์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๊ธฐํ ๋จ๊ณ์์ ์ด๋ฅผ ๊ฐ์งํ๊ณ ์๋ฌ๋ฅผ ๋ฐ์)
2. ์์ ์ ์ฃผ์ (Setter Injection)
์์ ์ ์ฃผ์ ์ ๊ฐ์ฒด ์์ฑ ํ, ํ์ํ ์์กด์ฑ์ setter ๋ฉ์๋๋ฅผ ํตํด ์ฃผ์ ํ๋ ๋ฐฉ์์ ๋๋ค. ์ด๋ ๊ฐ์ฒด์ ์์ฑ๊ณผ ์์กด์ฑ ์ฃผ์ ์ ๋ถ๋ฆฌํ์ฌ ๋ ์ ์ฐํ ๊ตฌ์ฑ์ด ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
์์ ์ฝ๋:
public class UserService {
private UserRepository userRepository;
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
์์ ์ฝ๋ ์์ธ ๋์ ์์:
UserService
๊ฐ์ฒด ์์ฑ.- ์คํ๋ง์ด
UserRepository
์์กด์ฑ์ ํ์ธ. UserRepository
์ธ์คํด์ค๋ฅผUserService
์setUserRepository
๋ฉ์๋๋ฅผ ํตํด ์ฃผ์ .
์ ์ฒด ๋์ ์์:
- ๋น ์์ฑ: ์คํ๋ง ์ปจํ ์ด๋๋ ๋จผ์ ๊ฐ์ฒด(๋น)๋ฅผ ์์ฑํฉ๋๋ค. ์ด ๋๋ ์์ง ์์กด์ฑ์ด ์ฃผ์ ๋์ง ์์ ์ํ์ ๋๋ค.
- ์์กด์ฑ ํ์ธ: ์คํ๋ง ์ปจํ ์ด๋๋ ๊ฐ์ฒด์ ํ์ํ ์์กด์ฑ์ ํ์ธํฉ๋๋ค.
- ์์กด์ฑ ์ฃผ์ : ์คํ๋ง ์ปจํ ์ด๋๋ ํด๋น ๊ฐ์ฒด์ ์์ ์ ๋ฉ์๋(setter)๋ฅผ ํธ์ถํ์ฌ ์์กด์ฑ์ ์ฃผ์ ํฉ๋๋ค.
์ฅ์ :
- ์ ์ฐ์ฑ: ์์กด์ฑ์ ๋์ค์ ์ฃผ์ ํ ์ ์์ด ์คํ ์ค์ ๊ฐ์ฒด์ ์์กด์ฑ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
- ์ ํ์ ์์กด์ฑ: ๋ชจ๋ ์์กด์ฑ์ด ํ์๋ ์๋๋ฏ๋ก ํ์์ ๋ฐ๋ผ ์ ํ์ ์ผ๋ก ์์กด์ฑ์ ์ฃผ์ ํ ์ ์์ต๋๋ค.
๋จ์ :
- ๋ถ์์ ํ ๊ฐ์ฒด ์์ฑ ๊ฐ๋ฅ์ฑ: ๋ชจ๋ ์์กด์ฑ์ด ์ค์ ๋๊ธฐ ์ ์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ํ์ด ์์ต๋๋ค.
3. ํ๋ ์ฃผ์ (Field Injection)
ํ๋ ์ฃผ์
์ ํด๋์ค ๋ด๋ถ์ ํ๋์ ์ง์ ์์กด์ฑ์ ์ฃผ์
ํ๋ ๋ฐฉ์์
๋๋ค. ์ฃผ๋ก @Autowired
์ด๋
ธ
ํ ์ด์ ์ ์ฌ์ฉํ์ฌ ๊ฐํธํ๊ฒ ์์กด์ฑ์ ์ฃผ์ ํ ์ ์์ต๋๋ค.
์์ ์ฝ๋:
public class OrderService {
@Autowired
private PaymentService paymentService;
}
์์ ์ฝ๋ ๋์ ์์:
OrderService
๊ฐ์ฒด ์์ฑ.- ์คํ๋ง์ด
PaymentService
ํ๋์@Autowired
๋ฅผ ์ธ์. - ํด๋น ํ๋์
PaymentService
์ธ์คํด์ค๋ฅผ ์๋์ผ๋ก ์ฃผ์ .
์ ์ฒด ๋์ ์์:
- ๋น ์์ฑ: ๊ฐ์ฒด(๋น)๊ฐ ์์ฑ๋ฉ๋๋ค.
- ์์กด์ฑ ์ฃผ์ : ์์ฑ๋ ๊ฐ์ฒด์ ํ๋์ ์ด๋ ธํ ์ด์ ์ด ๋ถ์ด ์๋ ๊ฒฝ์ฐ, ์คํ๋ง ์ปจํ ์ด๋๋ ํด๋น ํ๋์ ์ง์ ์์กด์ฑ์ ์ฃผ์
์ฅ์ :
- ๊ฐ๊ฒฐ์ฑ: ์ฝ๋๊ฐ ๊ฐ๋จํด์ ธ์ ๊ฐ๋ฐ ์๋๊ฐ ํฅ์๋ฉ๋๋ค.
- ํธ๋ฆฌ์ฑ: ์ค์ ์ ๋ฉ์๋๋ ์์ฑ์๋ฅผ ์ ์ํ ํ์ ์์ด ์๋์ผ๋ก ์์กด์ฑ์ด ๊ด๋ฆฌ๋ฉ๋๋ค.
๋จ์ :
- ํ ์คํธ ์ด๋ ค์: ๋จ์ ํ ์คํธ ์ ์์กด์ฑ์ ๋ช ์์ ์ผ๋ก ์ ๊ณตํ๊ธฐ ์ด๋ ค์์ง๋๋ค.
์ฆ ์ ๋งํด์ ์์ฑ์ ์ฃผ์ ์ ์ฌ์ฉํด์ผ ํ๋ฉฐ
์์ฑ์ ์ฃผ์ ์ ์ฅ์ ์ ์ ์ฒด์ ์ผ๋ก ์์ธํ ๋์ดํด๋ณด๊ฒ ๋ค
์ ์์ฑ์ ์ฃผ์ ์ ์ฌ์ฉํด์ผ ํ๋๊ฐ?
1. ์์กด์ฑ ๋ช ํ์ฑ๊ณผ ์์ ์ฑ
์์ฑ์๋ฅผ ํตํด ์์กด์ฑ์ ์ฃผ์ ๋ฐ๋ ๋ฐฉ์์ ๋ชจ๋ ํ์ ์์กด์ฑ์ด ์์ฑ ์์ ์ ์ ๊ณต๋์ด์ผ ํจ์ ์๋ฏธํฉ๋๋ค. ์ด ์ ๊ทผ ๋ฐฉ์์ ์์กด์ฑ ๋๋ฝ์ ๋ฐฉ์งํ๊ณ , ๋ฐํ์ ์ค๋ฅ์ ๊ฐ๋ฅ์ฑ์ ์ค์ ๋๋ค.
์์ ์ฝ๋:
public class AccountService {
private final AccountRepository accountRepository;
private final NotificationService notificationService;
public AccountService(AccountRepository accountRepository, NotificationService notificationService) {
this.accountRepository = accountRepository;
this.notificationService = notificationService;
}
}
์ ์ฝ๋์์ AccountService
๋ AccountRepository
์ NotificationService
์ ์์กด์ฑ์ ํ์๋ก ํฉ๋๋ค. ์ด ๋ ์ปดํฌ๋ํธ๋ ์์ฑ์๋ฅผ ํตํด ์ฃผ์
๋๋ฏ๋ก, AccountService
๊ฐ์ฒด๋ ํญ์ ์์ ํ ์ํ๋ก ์์ฑ๋ฉ๋๋ค.
2. ๋ถ๋ณ์ฑ ๋ณด์ฅ
์์ฑ์ ์ฃผ์ ์ ํตํ ์์กด์ฑ ๊ด๋ฆฌ๋ ๊ฐ์ฒด์ ๋ถ๋ณ์ฑ์ ๋ณด์ฅํฉ๋๋ค. ํ ๋ฒ ์ฃผ์ ๋ ์์กด์ฑ์ ๊ฐ์ฒด์ ์๋ช ์ฃผ๊ธฐ ๋์ ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค.
์์ ์ฝ๋:
public class Configuration {
private final String databaseUrl;
public Configuration(String databaseUrl) {
this.databaseUrl = databaseUrl;
}
public String getDatabaseUrl() {
return this.databaseUrl;
}
}
Configuration
๊ฐ์ฒด๋ ์์ฑ ์ databaseUrl
์ ์ฃผ์
๋ฐ์ผ๋ฉฐ, ์ด ๊ฐ์ ๊ฐ์ฒด๊ฐ ์กด์ฌํ๋ ๋์ ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค. ์ด๋ ๊ฐ์ฒด์ ์ผ๊ด๋ ์ํ๋ฅผ ์ ์งํ๋ ๋ฐ ์ค์ํฉ๋๋ค.
3. ์ํ ์ฐธ์กฐ ๋ฐฉ์ง
์์ฑ์ ์ฃผ์ ์ ์ํ ์ฐธ์กฐ๋ฅผ ์ปดํ์ผ ์์ ์์ ๊ฐ์งํ ์ ์๊ฒ ํด์ค๋๋ค. ์๋ก ์์กดํ๋ ๊ฐ์ฒด๊ฐ ์์ ๊ฒฝ์ฐ, ์คํ๋ง์ ์ด๊ธฐํ ์ค์ ์๋ฌ๋ฅผ ๋ฐ์์์ผ ๊ฐ๋ฐ์์๊ฒ ์๋ฆฝ๋๋ค.
์ํ ์ฐธ์กฐ ๋ฐ์ ์:
public class ClassA {
private final ClassB classB;
public ClassA(ClassB classB) {
this.classB = classB;
}
}
public class ClassB {
private final ClassA classA;
public ClassB(ClassA classA) {
this.classA = classA;
}
}
์ ์ฝ๋๋ ClassA
์ ClassB
๊ฐ ์๋ก๋ฅผ ํ์๋ก ํ๋ฏ๋ก ์ํ ์ฐธ์กฐ๊ฐ ๋ฐ์ํฉ๋๋ค. ์คํ๋ง์ ์ด๋ฅผ ๊ฐ์งํ๊ณ ๊ฐ์ฒด ์์ฑ์ ์ค๋จํฉ๋๋ค.
4. ํ ์คํธ ์ฉ์ด์ฑ
์์ฑ์ ์ฃผ์ ์ ํ ์คํธ ์ค์ ์์กด์ฑ์ ์ฝ๊ฒ ์ ์ดํ ์ ์๊ฒ ํด์ค๋๋ค. ํ ์คํธ ์์ ํ์ํ ์์กด์ฑ์ ๋ชฉ ๊ฐ์ฒด๋ก ์ ๊ณตํ ์ ์์ต๋๋ค.
์์ ์ฝ๋:
public class UserServiceTest {
@Test
public void testUserService() {
UserRepository mockRepository = mock(UserRepository.class);
NotificationService mockService = mock(NotificationService.class);
UserService userService = new UserService(mockRepository, mockService);
// ํ
์คํธ ์คํ
userService.performUpdate();
// ์ํ ๊ฒ์ฆ
verify(mockRepository).update(any(User.class));
verify(mockService).sendNotification(any(String.class));
}
}
์ ์ฝ๋์์ UserService
์ ํ
์คํธ๋ ๋ชฉ ๊ฐ์ฒด๋ฅผ ์์ฑ์๋ฅผ ํตํด ์ฃผ์
ํ์ฌ, ์ค์ ์์กด์ฑ์ ๋ชจ๋ฐฉํฉ๋๋ค. ์ด ๋ฐฉ์์ ํ
์คํธ๊ฐ ์์กด์ฑ์ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ์ ๋ฌถ์ด์ง ์๋๋ก ํด์ค๋๋ค.