개발지식

[SPRING] DI(Dependency Injection) 의존관계 주입, DI 컨테이너

우루쾅 2024. 2. 5. 19:11
728x90
반응형
SMALL

DI 의존관계 주입

객체 간의 의존성을 외부에서 주입하여 결합도를 낮추고 유연한 코드를 작성하는 방법입니다!

 

DI(Dependency Injection) 는 객체 간의 의존 관계를 외부에서 결정하여 객체가 필요한 의존성을 주입받는 개념입니다.

DI 를 통해 객체 간의 결합도를 낮출 수 있고, 코드의 재사용성과 테스트 용이성을 높일 수 있습니다.

 

DI 는 주로 생성자, 메서드 매개변수, 속성에 의해 의존성을 주입하며,

의존성을 관리하는 컨테이너를 활용하여 객체의 생성과 관리를 담당합니다.

이를 통해 유연하고 확장 가능한 애플리케이션을 개발할 수 있습니다!

 


스프링 DI를 코드 예시를 통해 확인을 해보자!

public interface MessageService {
    void sendMessage(String message);
}

public class EmailService implements MessageService {
    public void sendMessage(String message) {
        System.out.println("이메일을 보냅니다: " + message);
    }
}

public class SMSService implements MessageService {
    public void sendMessage(String message) {
        System.out.println("SMS를 보냅니다: " + message);
    }
}

public class NotificationService {
    private MessageService messageService;

    public NotificationService(MessageService messageService) {
        this.messageService = messageService;
    }

    public void sendNotification(String message) {
        messageService.sendMessage(message);
    }
}

 

위 코드에서 MessageService는 메시지를 보내는 기능을 갖는 인터페이스입니다.

EmailService와 SMSService는 MessageService를 구현한 구체적인 클래스입니다.

 

NotificationService 는 메시지를 보내는 역할을 하는 클래스이고,

이 클래스는 MessageService 객체를 의존하고 있으며, 생성자를 통해 의존성을 주입받습니다.

이렇게 의존성을 주입받는 것이 DI의 핵심 개념입니다.

 

이제 스프링 컨테이너를 사용하여 DI를 적용해보겠습니다!

 

@Configuration
public class AppConfig {
    @Bean
    public MessageService emailService() {
        return new EmailService();
    }

    @Bean
    public MessageService smsService() {
        return new SMSService();
    }

    @Bean
    public NotificationService notificationService(MessageService messageService) {
        return new NotificationService(messageService);
    }
}

 

위 코드는 스프링의 설정 파일인 AppConfig입니다.

@Configuration 어노테이션을 통해 스프링에게 이 클래스가 설정파일임을 알려줍니다

 

@Bean 어노테이션은 빈(Bean) 객체를 정의하는 메서드에 붙여줍니다.

emailService() 와 smsService() 메서드는 각각 EmailService와 SMSService 객체를 생성하여 반환합니다.

notificationService()메서드는 MessageService 객체를 파라미터로 받아서 NotificaionService 객체를 생성하고 반환합니다.

이렇게 MessageService 객체가 의존성으로 주입되어 DI가 이루어집니다.

 

이제 스프링 컨테이너를 초기화하고 빈 객체를 사용해보겠습니다!

 

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

        NotificationService notificationService = context.getBean(NotificationService.class);
        notificationService.sendNotification("안녕하세요!");

        ((ConfigurableApplicationContext) context).close();
    }
}

 

AnnotationConfigApplicationContext 클래스는 AppConfig 클래스를 설정으로 사용하여 스프링 컨테이너를 초기화합니다.

context.getBean(NotificationService.class) 를 호출하여 NotificationService 빈 객체를 가져옵니다.

이 때, 스프링 컨테이너는 NotificationService 객체를 생성하면서 의존성으로 MessageService 객체를 주입합니다.

notificationService.sendNotification("안녕하세요!") 를 호출하여 메시지를 전송하는 코드를 실행합니다.

이 때, NotificationService 객체 내부에서는 주입된 MessageService 객체의 sendMessage() 메서드를 호출하여 메시지를 보냅니다.

 

위의 예시 코드에서 DI는 NotificationService 에게 MessageService 객체를 주입함으로써(매개변수로 service 주입) 의존성을 해결하고, 결합도를 낮추는 효과를 얻을 수 있습니다. 이렇게 스프링 DI를 사용하면 유연하고 확장 가능한 코드를 작성할 수 있습니다!

 

● DI 컨테이너

유사한 개념으로 DI 컨테이너가 있는데 DI 개념을 구현하고 관리하는 구체적인 컨테이너로 객체들의 의존 관계를 설정하고 주입해주는 역할을 수행합니다. 주로 ApplicationContext 와 같은 클래스가 DI 컨테이너의 역할을 수행합니다.

즉, DI 는 개념, DI 컨테이너는 이론을 스프링 프레임워크를 통해 실체화 한 것으로 이해하면 됩니다!

 

 

한줄로 간단하게 정리하자면 

DI(Dependency Injection) 는 객체 간의 의존 관계를 외부에서 설정하고 주입하는 방법을 통해 객체 결합도를 낮추고 유연한 애플리캐이션 개발을 지원하는 스프링 기술입니다!

 

 

 

 

출처

인프런 - 김영한의 스프링 핵심원리 - 기본편 (IoC, DI, 그리고 컨테이너)

GPT-4(갓피티..)

728x90
반응형
LIST