본문 바로가기

Dev/Spring Boot

[예제로 배우는 스프링 입문] IoC 컨테이너와 의존성

오늘은 IoC에 대해 알아보겠다.

Inversion of  Control

1. 일반적인 경우, 내가 사용할 의존성은 내가 만든다.

class OwnerController{

           private OwnerRepository repository=new OwnerRepository(); // 직접 생성

}

// OwnerController은 repo객체를 클래스 안에서 직접 생성했다.

2. 역전된 경우

class OwnerController{

           private OwnerRepository repo;

           public OwnerController(OwnerRepository repo){

                                                        this.repo=repo;

           }
}

// OwnerController은 repo객체를 만들지 않고, 사용한다. 생성자를 통해 받아온다.

// 의존성을 관리하는 일을 OwnerController 밖에서 한다. 

// 의존성 주입 : dependency injection 도 일종의 loc라고 볼 수 있다. 외부 누군가로부터 얻어오기 때문에

 

OwnerController.java

OwnerController.java의 생성자 코드

OwnerController는 OwnerRepository 객체를 어디선가 받아오며 생성되고, 받아온 OwnerRepository 객체를 사용한다.

this.owners.save(owner); 코드를 실행하면 어떻게 될까? 오류가 날까?

 

예시로 샘플 코드를 작성해 보겠다.

sample 패키지 생성 후 2개 파일 생성

SampleController.java

위는 의존성(repository인스턴스)을 받아와 세팅하고, 사용하는 코드이다.

 

SampleControllerTest.java

Junit으로 doSomething()메소드를 호출해보겠다.

 doSomething() 호출하면 sampleRepository 인스턴스가 설정되지 않는한 sampleRepository.save()는 null pointer exception이 발생할 것이다. 그러나 SampleController 인스턴스를 만들기 위해서는 sampleRepository를 인자로 넣어줘야 하므로 미리 sampleRepository인스턴스를 생성해야 하므로 exception이 발생하지 않는다.

test/sample/SampleControllerTest.java 생성 위치는 아래와 같다.

 

다시 Owner 코드로 돌아가겠다.

OwnerController.java

OwnerController도 OwnerRepository 없이는 생성될 수 없다.

의존성을 주입하고, 그걸 사용해도 아무 문제가 없다. 

그러면 이 의존성(OwnerRepository)은 누가 넣어주는 걸까? 

 

test/java/owner/OwnerControllerTests.java

 

샘플 코드에서는 SampleControllerTest.java에서 new SampleController(sampleRepositry)를 넣어주었다.

Owner 코드의 경우는?

OwnerControllerTest에서 @MockBean 어노테이션을 붙인다.

 스프링이 관리하는 빈으로 등록되면, OwnerController에서 OwnerRepository를 빈에서 가져와서 사용할 수 있다. 이 의존성을 스프링에 있는 ioc 컨테이너가 주입해주는 것이다.