서론:객체 지향 설계의 새로운 패러다임
객체지향 프로그래밍에서 가장 주용한 원칙 중하나는 "느슨한 결한 (Loose Couping)" 입니다.하지만 기존의 자바 개발 방식에서는 객체간의 강한 의존 관계가 필연적으로 발생했습니다. Spring Framework가 등장하면서 이문제를 해결한 두가지 핵심 개념이 바로 IoC(Inversion of Control) 와 DI(Dependency Injection)입니다
1.IoC: 제어의 역전이란 무엇인가?
개념적 이해
IoC는 "제어의 역전"을 의미합니다. 기존 프로그래밍에서는 개발자가 모든 객체의 생성과 관리를 직접 제어했습니다. IoC에서는 이제어권이 프레임워크로 넘어갑니다.
public class OrderService {
// 개발자가 직접 객체 생성
private PaymentService paymentService = new PaymentService();
private EmailService emailService = new EmailService();
public void processOrder(Order order) {
paymentService.processPayment(order);
emailService.sendConfirmation(order);
}
}
IoC방식:
@Service
public class OrderService {
// Spring이 객체를 주입해줌
private final PaymentService paymentService;
private final EmailService emailService;
public OrderService(PaymentService paymentService, EmailService emailService) {
this.paymentService = paymentService;
this.emailService = emailService;
}
public void processOrder(Order order) {
paymentService.processPayment(order);
emailService.sendConfirmation(order);
}
}
2.DI: 의존성주입의 세가지 방식
DI는 IoC를 구현하는 구체적인 기술입니다. 객체가 필요로한 의존성을 외부에서 주입 해주는 방식입니다.
@Service
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
// 생성자를 통한 주입
public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
public User registerUser(String username, String password) {
String encodedPassword = passwordEncoder.encode(password);
User user = new User(username, encodedPassword);
return userRepository.save(user);
}
}
장점:
객체의 불변성 보장 (final 키워드 사용가능)
테스트하기 쉬움
순환참조 방지
Null 안전성
2.2 필드 주입
가장 간단해 보이지만 여러 문제점이 있어 권장되지 않습니다.
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Autowired
private CategoryRepository categoryRepository;
public Product createProduct(Product product, Long categoryId) {
Category category = categoryRepository.findById(categoryId)
.orElseThrow(() -> new CategoryNotFoundException(categoryId));
product.setCategory(category);
return productRepository.save(product);
}
}
문제점:
테스트 시 리플렉션을 사용해야 함
불변성 보장 불가능
의존 관계가 명시적이지 않음
2.3 수정자 주입
선택적 의존성이나 런타임에 의존성을 변경해야 할떄 사용합니다.
@Service
public class NotificationService {
private EmailSender emailSender;
private SmsSender smsSender;
@Autowired
public void setEmailSender(EmailSender emailSender) {
this.emailSender = emailSender;
}
@Autowired
public void setSmsSender(SmsSender smsSender) {
this.smsSender = smsSender;
}
}
결론:
그래서 개발할때생성자 주입을 권장합니다 저도 개발할때 생성자주입을 주로 사용합니다.
'개발 공부 > Java-Spring' 카테고리의 다른 글
| [JPA] 엔티티의 생명주기 3단계 (0) | 2026.05.10 |
|---|---|
| [Java] final, static, static final 차이점 완벽 정리 (0) | 2026.05.09 |
| 자바 접근 제어자및 스프링부트에서 사용예시 (0) | 2026.01.20 |
| [JPA] N+1 문제, 원인과 결과로 완벽하게 이해하기 (0) | 2026.01.20 |
| 불변의 객체 의 정의 (0) | 2025.12.10 |