ποΈ[SpringBoot] μ€νλ§ λΆνΈμ ν΅μ¬ κ°λ - μμ‘΄μ± μ£Όμ
π κ°μ
Spring Frameworkμ ν΅μ¬ κ°λ μ€ νλμΈ μμ‘΄μ± μ£Όμ (Dependency Injection) κ³Ό μ μ΄μ μμ (Inversion of Control) μ λν΄ μμλ΄ λλ€. μ΄λ SpringBoot μ ν리μΌμ΄μ κ°λ°μ κΈ°μ΄κ° λλ λ§€μ° μ€μν κ°λ μ λλ€.
π§© μμ‘΄μ±(Dependency)μ΄λ?
κΈ°λ³Έ κ°λ
- μμ‘΄μ±: ν ν΄λμ€κ° λμνκΈ° μν΄ λ€λ₯Έ ν΄λμ€κ° νμν κ΄κ³
- νν λ°©μ: βA ν΄λμ€κ° B ν΄λμ€μ μμ‘΄νλ€β λλ βB ν΄λμ€κ° A ν΄λμ€μ μμ‘΄μ±μ΄λ€β
Java νλ‘κ·Έλλ°μμμ μμ‘΄μ±
public class OrderService {
private PaymentService paymentService;
public OrderService() {
this.paymentService = new PaymentService(); // OrderServiceκ° PaymentServiceμ μμ‘΄
}
}
β μ€μ΅ μμ : μ»€νΌ λ©μ΄μ»€ μμ€ν
1λ¨κ³: κΈ°λ³Έμ μΈ μμ‘΄μ± κ΄κ³ ꡬν
EspressoMachine ν΄λμ€
public class EspressoMachine {
public String brew() {
return "Brewing coffee with Espresso Machine";
}
}
CoffeeMaker ν΄λμ€
public class CoffeeMaker {
private EspressoMachine espressoMachine;
public CoffeeMaker() {
this.espressoMachine = new EspressoMachine(); // μ§μ μμ‘΄μ± μμ±
}
public void makeCoffee() {
System.out.println(espressoMachine.brew());
}
}
μ€ν μ½λ
public class Main {
public static void main(String[] args) {
CoffeeMaker coffeeMaker = new CoffeeMaker();
coffeeMaker.makeCoffee();
// μΆλ ₯: Brewing coffee with Espresso Machine
}
}
π¨ λ¨λ¨ν κ²°ν©(Tight Coupling)μ λ¬Έμ μ
λ¬Έμ μν©
μλ‘μ΄ λ립 μ»€νΌ λ¨Έμ μ μΆκ°νκ³ μΆλ€λ©΄?
DripCoffeeMachine ν΄λμ€
public class DripCoffeeMachine {
public String brew() {
return "Brewing coffee with Drip Coffee Machine";
}
}
κΈ°μ‘΄ CoffeeMaker ν΄λμ€ μμ νμ
public class CoffeeMaker {
// private EspressoMachine espressoMachine; // μμ
private DripCoffeeMachine dripCoffeeMachine; // μΆκ°
public CoffeeMaker() {
// this.espressoMachine = new EspressoMachine(); // μμ
this.dripCoffeeMachine = new DripCoffeeMachine(); // μΆκ°
}
public void makeCoffee() {
// System.out.println(espressoMachine.brew()); // μμ
System.out.println(dripCoffeeMachine.brew()); // μΆκ°
}
}
λ¨λ¨ν κ²°ν©μ λ¨μ
- π μ½λ μμ λ²μ νλ: μμ‘΄μ± ν΄λμ€ λ³κ²½ μ μ¬μ©νλ λͺ¨λ ν΄λμ€λ μμ νμ
- π μ μ§λ³΄μ μ΄λ €μ: μ¬λ¬ κ³³μ ν©μ΄μ§ μ½λλ₯Ό λͺ¨λ μ°Ύμμ μμ
- π§ͺ ν μ€νΈ μ΄λ €μ: Mock κ°μ²΄ μ¬μ©μ΄ μ΄λ €μ
- π νμ₯μ± λΆμ‘±: μλ‘μ΄ κ΅¬ν체 μΆκ° μ κΈ°μ‘΄ μ½λ λ³κ²½ λΆκ°νΌ
π λμ¨ν κ²°ν©(Loose Coupling)μΌλ‘μ μ ν
1λ¨κ³: μΈν°νμ΄μ€ μ μ
public interface CoffeeMachine {
String brew();
}
2λ¨κ³: ꡬν체λ€μ΄ μΈν°νμ΄μ€ ꡬν
public class EspressoMachine implements CoffeeMachine {
@Override
public String brew() {
return "Brewing coffee with Espresso Machine";
}
}
public class DripCoffeeMachine implements CoffeeMachine {
@Override
public String brew() {
return "Brewing coffee with Drip Coffee Machine";
}
}
3λ¨κ³: CoffeeMaker ν΄λμ€ λ¦¬ν©ν λ§
public class CoffeeMaker {
private CoffeeMachine coffeeMachine;
// μμ‘΄μ±μ μΈλΆμμ μ£Όμ
λ°λ λ©μλ
public void setCoffeeMachine(CoffeeMachine coffeeMachine) {
this.coffeeMachine = coffeeMachine;
}
public void makeCoffee() {
System.out.println(coffeeMachine.brew());
}
}
4λ¨κ³: μΈλΆμμ μμ‘΄μ± μ£Όμ
public class Main {
public static void main(String[] args) {
CoffeeMaker coffeeMaker = new CoffeeMaker();
// λ립 μ»€νΌ λ¨Έμ μ¬μ©
coffeeMaker.setCoffeeMachine(new DripCoffeeMachine());
coffeeMaker.makeCoffee();
// μμ€νλ μ λ¨Έμ μΌλ‘ μ½κ² λ³κ²½
coffeeMaker.setCoffeeMachine(new EspressoMachine());
coffeeMaker.makeCoffee();
}
}
β¨ μμ‘΄μ± μ£Όμ μ μ₯μ
π― μ μ°μ± (Flexibility)
// μλ‘μ΄ λͺ¨μΉ΄ λ¨Έμ μΆκ° - CoffeeMaker μ½λ λ³κ²½ μμ!
public class MokaCoffeeMachine implements CoffeeMachine {
@Override
public String brew() {
return "Brewing coffee with Moka Coffee Machine";
}
}
// μ¬μ© μ
coffeeMaker.setCoffeeMachine(new MokaCoffeeMachine());
π§ͺ ν μ€νΈ μ©μ΄μ± (Testability)
// ν
μ€νΈλ₯Ό μν Mock κ°μ²΄ μ½κ² μ¬μ© κ°λ₯
public class MockCoffeeMachine implements CoffeeMachine {
@Override
public String brew() {
return "Mock brewing for test";
}
}
// ν
μ€νΈ μ½λμμ
coffeeMaker.setCoffeeMachine(new MockCoffeeMachine());
π§ μ μ§λ³΄μμ± (Maintainability)
- μλ‘μ΄ κ΅¬ν체 μΆκ° μ κΈ°μ‘΄ μ½λ λ³κ²½ λΆνμ
- κ° ν΄λμ€μ μ± μμ΄ λͺ ννκ² λΆλ¦¬
- μΈν°νμ΄μ€ κΈ°λ° μ€κ³λ‘ νμ₯μ± ν보
ποΈ Springμμμ μμ‘΄μ± μ£Όμ
Spring Containerμ μν
SpringBootμμλ Spring Containerκ° λ€μκ³Ό κ°μ μν μ λ΄λΉν©λλ€:
- π¦ κ°μ²΄ μμ±: μ ν리μΌμ΄μ μ νμν λͺ¨λ Bean κ°μ²΄λ₯Ό μμ±
- π μμ‘΄μ± μ°κ²°: κ°μ²΄λ€ κ°μ μμ‘΄μ±μ μλμΌλ‘ μ£Όμ
- β»οΈ μλͺ μ£ΌκΈ° κ΄λ¦¬: κ°μ²΄μ μμ±λΆν° μλ©ΈκΉμ§ μ 체 μλͺ μ£ΌκΈ°λ₯Ό κ΄λ¦¬
Springμ μμ‘΄μ± μ£Όμ λ°©λ²
1. μμ±μ μ£Όμ (κΆμ₯)
@Service
public class CoffeeMaker {
private final CoffeeMachine coffeeMachine;
public CoffeeMaker(CoffeeMachine coffeeMachine) {
this.coffeeMachine = coffeeMachine;
}
}
2. Setter μ£Όμ
@Service
public class CoffeeMaker {
private CoffeeMachine coffeeMachine;
@Autowired
public void setCoffeeMachine(CoffeeMachine coffeeMachine) {
this.coffeeMachine = coffeeMachine;
}
}
3. νλ μ£Όμ
@Service
public class CoffeeMaker {
@Autowired
private CoffeeMachine coffeeMachine;
}
Spring Bean λ±λ‘
@Component
public class EspressoMachine implements CoffeeMachine {
// ꡬν λ΄μ©
}
@Component
public class DripCoffeeMachine implements CoffeeMachine {
// ꡬν λ΄μ©
}
π― ν΅μ¬ κ°λ μ 리
μμ‘΄μ± μ£Όμ (Dependency Injection)
κ°μ²΄κ° νμλ‘ νλ μμ‘΄μ±μ μΈλΆμμ μμ±νμ¬ μ£Όμ νλ μ€κ³ ν¨ν΄
μ μ΄μ μμ (Inversion of Control)
κ°μ²΄μ μμ±κ³Ό κ΄λ¦¬ μ± μμ κ°λ°μμμ νλ μμν¬(Spring Container)λ‘ μ΄μ
μ₯μ μμ½
- β κ²°ν©λ κ°μ: ν΄λμ€ κ° μμ‘΄μ±μ μΈν°νμ΄μ€λ‘ μΆμν
- β μ¬μ¬μ©μ± μ¦κ°: λ€μν ꡬν체λ₯Ό μ½κ² κ΅μ²΄ κ°λ₯
- β ν μ€νΈ μ©μ΄: Mock κ°μ²΄λ₯Ό ν΅ν λ¨μ ν μ€νΈ κ°νΈν
- β μ μ§λ³΄μμ±: μλ‘μ΄ κΈ°λ₯ μΆκ° μ κΈ°μ‘΄ μ½λ λ³κ²½ μ΅μν
π λ€μ λ¨κ³
μμ‘΄μ± μ£Όμ μ μ΄ν΄νλ€λ©΄ λ€μ κ°λ λ€μ νμ΅ν΄λ³΄μΈμ:
- Spring Beanκ³Ό Component Scan
- λ€μν μμ‘΄μ± μ£Όμ μ λ Έν μ΄μ (@Autowired, @Qualifier, @Primary)
- Bean Scope (Singleton, Prototype λ±)
- κ΄μ μ§ν₯ νλ‘κ·Έλλ° (AOP)
π‘ μ€λ¬΄ ν
μμ±μ μ£Όμ μ κΆμ₯νλ μ΄μ
@Service
public class OrderService {
private final PaymentService paymentService;
private final EmailService emailService;
// final νλλ‘ λΆλ³μ± 보μ₯
public OrderService(PaymentService paymentService, EmailService emailService) {
this.paymentService = paymentService;
this.emailService = emailService;
}
}
- λΆλ³μ± 보μ₯: final ν€μλλ‘ κ°μ²΄ μν 보νΈ
- νμ μμ‘΄μ± λ³΄μ₯: κ°μ²΄ μμ± μ λͺ¨λ μμ‘΄μ±μ΄ μ£Όμ λ¨μ 보μ₯
- ν μ€νΈ μΉνμ : μμ±μλ₯Ό ν΅ν΄ μ½κ² Mock κ°μ²΄ μ£Όμ κ°λ₯
Spring Frameworkλ μ΄λ¬ν μμ‘΄μ± μ£Όμ μ ν΅ν΄ λμ¨ν κ²°ν©μ μ μ§νλ©΄μλ κ°λ ₯ν κΈ°λ₯μ μ 곡νλ μ ν리μΌμ΄μ κ°λ°μ κ°λ₯νκ² ν©λλ€.