의존성주입방식 살펴보기

Today Jeeho Learned·2022년 6월 27일
0

Spring

목록 보기
19/31

DI(Dependency Injection)

DI(Dependency Injection)란 스프링이 다른 프레임워크와 차별화되어 제공하는 의존 관계 주입 기능으로,
객체를 직접 생성하는 게 아니라 외부에서 생성한 후 주입 시켜주는 방식이다.

DI(의존성 주입)를 통해서 모듈 간의 결합도가 낮아지고 유연성이 높아진다.

첫번째 방법은 A객체가 B와 C객체를 New 생성자를 통해서 직접 생성하는 방법이고,

두번째 방법은 외부에서 생성 된 객체를 setter()를 통해 사용하는 방법이다.

이러한 두번째 방식이 의존성 주입의 예시인데,
A 객체에서 B, C객체를 사용(의존)할 때 A 객체에서 직접 생성 하는 것이 아니라 외부(IOC컨테이너)에서 생성된 B, C객체를 조립(주입)시켜 setter 혹은 생성자를 통해 사용하는 방식이다.

스프링에서는 객체를 Bean이라고 부르며, 프로젝트가 실행될때 사용자가 Bean으로 관리하는 객체들의 생성과 소멸에 관련된 작업을 자동적으로 수행해주는데 객체가 생성되는 곳을 스프링에서는 Bean 컨테이너라고 부른다.

Ioc(Inversion of Control)

IoC(Inversion of Control)란 "제어의 역전" 이라는 의미로, 말 그대로 메소드나 객체의 호출작업을 개발자가 결정하는 것이 아니라, 외부에서 결정되는 것을 의미한다.

IoC는 제어의 역전이라고 말하며, 간단히 말해 "제어의 흐름을 바꾼다"라고 한다.

객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복, 유지 보수를 편하게 할 수 있게 한다.

기존에는 다음과 순서로 객체가 만들어지고 실행되었다.

1.객체 생성

  1. 의존성 객체 생성
  2. 클래스 내부에서 생성

의존성 객체 메소드 호출

하지만, 스프링에서는 다음과 같은 순서로 객체가 만들어지고 실행된다.

  1. 객체 생성

  2. 의존성 객체 주입
    스스로가 만드는것이 아니라 제어권을 스프링에게 위임하여 스프링이 만들어놓은 객체를 주입한다.

  3. 의존성 객체 메소드 호출

스프링이 모든 의존성 객체를 스프링이 실행될때 다 만들어주고 필요한곳에 주입시켜줌으로써 Bean들은 싱글턴 패턴의 특징을 가지며,

제어의 흐름을 사용자가 컨트롤 하는 것이 아니라 스프링에게 맡겨 작업을 처리하게 된다.

생성자주입을 사용하자

1 생성자 주입

public class Foo {
    private final Bar bar;
    
    @Autowired
    public Foo(Bar bar) {
    	this.bar = bar;
    }
}

이렇게 코드를 작성하면 Foo객체를 생성할 때 bar 객체를 매개변수로 전달해 주면 의존성 주입이 됩니다.

장점으로는 단위 테스트가 쉽고, 주입받는 객체의 final 선언이 가능합니다.

또한 객체의 생성자는 1번 호출되는 것이 보장되기 때문에 주입받은 객체가 변하지 않거나, 반드시 객체의 주입이 필요할 때 사용할 수 있습니다.

Spring Framework에서도 생성자 주입 방식을 적극 권장하기 때문에, 생성자가 1개인 경우 @Autowired 어노테이션을 생략할 수 도 있습니다.

2. setter 주입

public class Foo {
    private Bar bar;
    
    @Autowired
    publid void setBar(Bar bar) {
    	this.bar = bar;
    }
}

setter보다 그냥 생성자쓰는게 낫다!

spring bean 생성 방법

@Bean

외부 라이브러리에서 정의한 클래스를 스프링 Bean으로 등록하고자 하는 경우에 사용합니다.

@Component

개발자가 직접 작성한 클래스를 스프링 Bean으로 등록할 경우 사용합니다.

@Component어노테이션은 아래 세 가지 중에 정확히 어디에 속하는지 모르는 경우에 사용합니다.

@Controller - 기본적으로 @Component와 같으나 presentation layer의 component라는 것 표기
@Service - 기본적으로 @Component와 같으나 business layer의 component라는 것 표기
@Repository - 기본적으로 @Component와 같으나 persistence layer의 component라는 것 표기

@Bean과 @Component의 차이는 외부 라이브러리에서 정의한 거냐, 개발자가 직접 정의하는 거냐의 차이입니다.

@Controller, @Service, @Repository는 Component 간에 구분할 때 사용하는 어노테이션입니다.

Presentaion Layer는 주로 클라이언트에서 보낸 요청 간의 json 형태로의 변환 등의 작업을 수행합니다.

Business Layer는 Presentation Layer에서 보내온 데이터를 가지고 비즈니스 로직에 따른 계산, 처리를 수행합니다.

Persistence Layer는 주로 데이터베이스와의 연결을 유지하고 데이터를 송, 수신합니다.

스프링 컨테이너

이제 본격적으로 IoC에 대해 얘기하기 위해 또 다른 개념 하나를 소개하겠습니다.

스프링 컨테이너는 IoC/Bean/DI 컨테이너라고 불리기도 합니다.

일반적으로 컨테이너는 인스턴스의 생명주기를 관리하고, 생성된 인스턴스들에게 추가적인 기능을 제공하도록 합니다.

프로그래머가 작성한 코드를 스스로 참조하고 알아서 객체의 생성과 소멸을 컨트롤해줍니다.
즉, 스프링 컨테이너에서 Bean들을 다 담아놓고, Bean의 생성, 소멸, 명세까지 전부 관리합니다.

오브젝트 생성을 개발자가 new 키워드를 통해 하지 않고 컨테이너가 호출하기 때문에 DI가 되는 것입니다.
DI가 되기 때문에 스프링 컨테이너가 스스로 제어할 수 있습니다.

이게 바로 IoC(Inversion of Control), 제어의 역전입니다.

개발자가 제어하던 프로그램의 흐름, 객체의 생성, 소멸 등을 컨테이너가 제어하기 때문에 제어의 역전이라고 불립니다.

사람이 하던 일을 스프링 프레임워크가 대신해주고, 개발자는 코드만 짜 놓고 실행만 하면 스프링이 알아서 해줍니다.

참고

https://velog.io/@gillog/Spring-DIDependency-Injection

profile
기록해야 (살아)남는다 !

0개의 댓글