본문 바로가기

Blog/Spring

스프링 프레임워크 입문 - Inversion of Control

 

  • Inversion of Control

제어권이 역전된 것

일반적인 (의존성에 대한) 제어권 : "내가 사용할 의존성은 내가 만든다."

 

class OwnerController{

    private OwnerRepository repository = new OwnerRepository();

} 

-> 일반적인 경우에는 자기가 사용할 의존성을 자기가 만들어서 사용한다. 그런데 이 의존성에 대한 제어권이 역전되었다고 생각해보면 의존성에 대한 제어권은 원래는 자기 자신이 가지고 있었는데 (자기가 사용할 의존성을 자기가 만들어서 자기가 관리하는 것) 그런데 오너 컨트롤러가 직접 관리하는게 아니라 

 

IoC : "내가 사용할 의존성을 누군가 알아서 주겠지"

> 내가 사용할 의존성의 타입(또는 인터페이스)만 맞으면 어떤 거든 상관없다.

> 그래야 내 코드 테스트 하기도 편하다.

 

 

class OwnerController{

    //repo 사용한다. 하지만 여기서 직접 만들지는 않는다. 
    private OwnerRepository repo;

    public OwnerController(OwnerRepository repo{

    	this.repo = repo;

    }

}

누군가가 밖에서 오너 컨트롤러 코드 밖에서 누군가가 줄 수 있게끔 생성자를 통해 받아오는 것

이는 의존성을 만드는 일은 더 이상 오너 컨트롤러로 하는 것이 아님, 이 의존성을 관리하는 일은 누군가 오너 컨트롤러 밖에서 해주는 것... 이것이 바로 의존성 제어권이 역전되었다고 보는 것

 

의존성을 주입해주는 것이 dependency injection 이라고 하는데 이것도 일종의 ioc 라고 볼 수 있다. 

왜? 의존성을 관리하는 그 자체 그 제어권을 인버전 했기 때문에 (역전)

 

 

       - 코드를 통해 보기

OwnerController를 보면 OwnerRepository 를 만들어서 사용하고 있음

이 때 OwnerController가 OwnerRepository의 인스턴스를 만들어서 인수로 넣어주고 사용함

오너 컨트롤러도 오너 컨트롤러 테스트 에서 ownerRepository를 mockBean이라는 어노테이션을 써줘서 (MockBean : 목 객체를 만들어서 빈으로 등록해주는 어노테이션, Bean : 스프링이 관리하는 객체 )

이렇게 하면 이 타입의 인스턴스를 스프링이 테스트를 만들 때 자동으로 만들어준다. = 이 오너 컨트롤러를 만들 때 빈을 가져와서 자동으로 주입해준다. 스프링이(스프링의 ioc 컨테이너가)

스프링이 빈이라는 객체를 관리한다. 빈들의 의존성을 관리하고 빈들의 객체 를 만들어서 빈으로 등록해주고 그렇게 만들어진 객체들을 이제 스프링 컨테이너 안에 있으니까 빈이라고 부르는 것(이렇게 의존성 관리, 필요한 의존성을 서로 주입해준다. 어떤 특정한 생성자나 어노테이션을 보고 주입을 해줄 수 있다.)

 

sample 패키지 안에 

sampleRepository.java

public class SampleRepository {

    public void save() {

    }

}

 

sampleController.java

package org.springframework.samples.petclinic.sample;



public class SampleController {

	SampleRepository sampleRepository;



    public SampleController(SampleRepository sampleRepository) {

    	this.sampleRepository = sampleRepository;

    }



    public void doSomething(){

    	sampleRepository.save();

    }

}

 

 

sampleControllerTest.java

package org.springframework.samples.petclinic.sample;



public class SampleControllerTest {



    @Test
    public void testDoSomething(){

    	SampleRepository sampleRepository = new SampleRepository();

    	SampleController sampleController = new SampleController(sampleRepository);



    }

}

sampleControllerTest에서는 sampleController를 쓰려면 sampleRepository를 만들어야만 가능하다.

생성자가 하나 뿐이기 때문에 들어가는 인자가 딱 정해져 있으므로

=> 안전하다.