본문 바로가기

개발공부/Spring

Spring - 의존성 주입

728x90
반응형

지금까지 우리가 프로그래밍을 할 때는 어떤 한 클래스가 다른 클래스의 기능을 사용하려면 당연히 개발자가 직접 코드에서 사용할 클래스의 생성자를 호출해서 사용했다.

즉, 사용될 클래스의 관계는 개발자에 의해 직접 코드에서 부여된다.

 

의존성 주입이란 이런 연관 관계를 개발자가 직접 코딩을 통해 컴포넌트(클래스)에 부여하는것이 아니라 컨테이너가 연관 관계를 직접 규정하는것이다.

그러면 코드에서 직접적인 연관 관계가 발생하지 않으므로 각 클래스들의 변경이 자유로워진다.

 

전체 어플리케이션은 각각의 기능을 담당하는 컴포넌트들로 이루어진다. 그리고 각 컴포넌트들은 다시 세부 기능을 수행하는 클래스들로 이루어진다. 그런데 컴포넌트를 이루는 클래스들이 다른 클래스의 기능을 사용하려면 어떻게 해야할까? 소스 코드에서 다른 클래스의 생성자를 호출해서 사용할 경우 기능을 구현하는 과정에서 다른 변경 사항이 발생하면 빠르게 대처하기가 어렵다. 관련이 있는 모든 클래스들의 소스코드를 수정해 주어야 하기 때문이다.

 

따라서 스프링 프레임워크에서는 각 클래스들의 연관 관계를 클래스들 사이에서 맺는 것이 아니라 스프링 프레임워크에서 설정을 통해 맺어줌으로써 클래스들이 연관 관계를 갖지 않게 구현했다.

 

 

* 의존성 주입(Dependency Injection, DI)

의존성 주입(Dependency Injection, DI)이란, 객체간의 의존 관계를 빈 설정 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것을 말합니다. 즉, 객체가 사용하는 의존 객체를 직접 생성하거나 검색하지 않고, 외부에서 생성된 객체를 전달받아 사용하는 방법입니다.

 

의존성 주입을 적용했을 때 얻을 수 있는 장점- 클래스들 간의 의존관계를 최소화 하여 코드를 단순화 할 수 있다.- 애플리케이션을 더 쉽게 유지 및 관리할 수 있다.- 기존 구현 방법은 개발자가 직접 코드 안에서 객체의 생성과 소멸을 제어 했지만 의존성 주입은 객체의 생성, 소멸과 객체간 의존 관계를 컨테이너가 제어한다.

 

Spring Framework에서는 의존성 주입을 지원하기 위해 다양한 방법을 제공합니다. 대표적인 방법으로는 생성자 주입(Constructor Injection), Setter 주입(Setter Injection), 필드 주입(Field Injection) 등이 있습니다.

 

예시)

public class Car {
    private Engine engine;

    // 생성자 주입
    public Car(Engine engine) {
        this.engine = engine;
    }

    // Setter 주입
    public void setEngine(Engine engine) {
        this.engine = engine;
    }

    // 필드 주입
    @Autowired
    private Transmission transmission;
}
더보기
* 생성자

객체를 생성할 때 필요한 초기화 작업을 수행하기 위해서 생성자를 사용합니다. 생성자는 객체를 생성할 때 자동으로 호출되며, 객체를 초기화하는 데 사용됩니다. 객체의 상태를 초기화하고, 필요한 리소스를 할당하거나, 의존 객체를 주입받는 등의 작업을 수행합니다.

객체를 초기화하는 이유는 객체를 사용하기 위해 필요한 상태 정보를 설정하거나, 객체가 필요로 하는 자원을 할당하는 등의 작업이 필요하기 때문입니다. 초기화를 하지 않은 객체는 사용할 수 없으며, NullPointerException 등의 예외가 발생할 수 있습니다.

또한, 생성자를 사용하면 객체 생성 시 필수적으로 전달해야 하는 인자 값을 명시할 수 있습니다. 이를 통해 객체 생성 시 필요한 인자를 누락하는 오류를 방지할 수 있습니다. 또한 생성자를 사용하면 객체의 불변성(Immutability)을 보장할 수 있습니다. 객체가 생성된 이후에는 생성자를 통해 설정한 값이 변경될 수 없으므로, 객체의 안정성과 일관성을 보장할 수 있습니다.

따라서, 객체의 초기화 작업을 수행하기 위해서 생성자를 사용합니다.


생성자 주입(Constructor Injection)은 의존성 주입(Dependency Injection, DI) 방법 중 하나로, 객체를 생성할 때 생성자를 통해 의존 객체를 주입하는 방법을 말합니다. 즉, 생성자를 통해 필요한 의존 객체를 전달받아 객체를 생성하는 방식입니다.

Spring Framework에서 생성자 주입은 XML, Java Config, 어노테이션 등 다양한 방법을 제공합니다.

 

위 예시에서 Car 클래스는 Engine 객체를 사용합니다. 이때, Car 클래스의 생성자, Setter, 필드에 Engine 객체를 주입하도록 설정해둡니다.

생성자 주입을 사용하면 객체 생성 시점에 필요한 의존 객체를 모두 주입할 수 있습니다. Setter 주입은 생성자와 비슷하지만, 의존 객체를 변경하거나 추가할 수 있는 유연성을 가지고 있습니다. 필드 주입은 객체 생성 후에 주입되기 때문에 생성자와 Setter 주입에 비해 초기화 순서와 예외 처리 등에 대한 고려가 필요합니다.

Spring에서는 @Autowired 어노테이션을 사용하여 의존성 주입을 자동화할 수 있습니다. @Autowired 어노테이션은 타입 기반으로 의존 객체를 검색하고, 해당 타입의 빈이 여러 개인 경우 @Qualifier 어노테이션을 사용하여 빈의 이름을 지정할 수 있습니다.

 

스프링에서 의존성 주입(DI)을 구현하려면  XML이나 애너테이션을 이용해 객체를 주입하여 객체들의 의존 관계를 맺어주면 된다. 즉 의존성 주입(DI)을 사용하여 각 객체들 간의 의존 관계를 최소화 함으로써 코드를 단순화하고 유지보수를 쉽게 할 수 있따.

 

의존성 주입(DI)은 객체의 생성, 소멸, 의존 관계를 개발자가 직접 설정하는 것이 아니라 XML이나 애너테이션 설정을 통해 경량 컨테이너에 해당하는 스프링 프레임 워크가 제어한다.

따라서 기존 코드에서는 개발자가 직접 객체를 제어했지만 스프링 프레임워크에서는 객체의 제어를 스프링이 직접 담당하므로 제어의 역전(IoC)라고 하는것이다. IoC의 종류도 여러 가지이며 일반적으로 스프링에서는 DI로 IoC의 기능을 구현하므로 IoC보다는 DI라는 용어를 더 많이 사용한다.

 

 

* 제어의 역전(IoC, Inversion of Control)

 

IoC는 컨테이너가 객체를 관리하고 의존성을 주입해주기 때문에 객체 간의 결합도를 낮추고, 유지보수성과 확장성을 높일 수 있습니다. 개발자는 객체의 생성과 의존성 주입에 대한 로직을 작성하지 않고도, 컨테이너에게 객체 생성과 의존성 주입을 위임함으로써 객체 간의 결합도를 낮출 수 있습니다.

스프링 프레임워크는 IoC를 구현한 대표적인 프레임워크 중 하나입니다. 스프링은 BeanFactory와 ApplicationContext를 제공하여 IoC를 구현하고, 객체의 라이프사이클과 의존성 주입 등의 작업을 수행합니다.

스프링은 XML, Annotation 등 다양한 방식을 통해 객체를 정의하고, 필요한 의존성을 자동으로 주입해주는 등의 기능을 제공합니다.

 

728x90
반응형

'개발공부 > Spring' 카테고리의 다른 글

project 이미지 데이터  (0) 2023.09.07
스프링 프레임워크(Spring Framework) MVC  (0) 2023.05.01