의존성 주입은 소프트웨어 디자인 패턴 중 하나로, 객체 간의 의존 관계를 코드 내부에서 직접 생성하지 않고 외부에서 주입하는 방식이다. 이를 통해 객체는 다른 객체와의 결합도가 낮아지며, 유지보수성과 테스트의 용이성이 향상된다.
의존성 주입은 생정자 주입, 세터 주입, 필드 주입의 세 가지 방식으로 구현할 수 있다.
public interface MessageService {
void sendMessage(String message);
}
public class EmailService implements MessageService {
@Override
public void sendMessage(String message) {
System.out.println("Email sent: " + message);
}
}
public class NotificationSender {
private MessageService messageService;
// 생성자 주입
public NotificationSender(MessageService messageService) {
this.messageService = messageService;
}
public void notify(String message) {
messageService.sendMessage(message);
}
}
public class Main {
public static void main(String[] args) {
// 의존성을 주입하여 객체 생성
MessageService service = new EmailService();
NotificationSender sender = new NotificationSender(service);
// 메서드 실행
sender.notify("Hello, Dependency Injection!");
}
public interface MessageService {
void sendMessage(String message);
}
public class EmailService implements MessageService {
@Override
public void sendMessage(String message) {
System.out.println("Email sent: " + message);
}
}
public class NotifiactionSender {
private MessageService messageService;
// 세터 메서드를 통한 의존성 주입
public void setMessageService(MessageService messageService) {
this.messageService = messageService;
}
public void notify(String message) {
if (messageService != null) {
messageService.sendMessage(message);
} else {
System.out.println("MessageService is not set");
}
}
}
public class Main {
public static void main(String[] args) {
// 객체 생성
MessageService service = new EmailService();
NotificationSender sender = new NotificationSender();
// 세터 메서드로 의존성 주입
sender.setMessageService(service);
// 메서드 실행
sender.notify("Hello with Setter Injection!");
}
}
public class NotificationSender {
// 필드 직접 주입(권장되지 않는 방식이다.)
public MessageService messageService;
public void notify(String message) {
if (messageService != null) {
messageService.sendMessage(message);
} else {
System.out.println("MessageService is not set");
}
}
}
public class Main {
public static void main(String[] args) {
MessageService service = new EmailService();
NotificationSender sender = new NotificationSender();
sender.messageService = service;
sender.notify("Hello with Field Injection!);
}
}
@Autowired 애너테이션을 필드에 붙여 의존성을 자동으로 주입한다.따라서, 객체의 불변성을 유지하고 의존성을 강제해야 한다면 생성자 주입을, 유연하게 선택적 의존성을 추가해야 한다면 세터 주입을, 코드의 간결성만 중요하고 테스트 및 유지보수에 대한 요구가 적다면 필드 주입을 사용하는 것이 좋다.