hmk run dev

스프링의 핵심 본문

spring

스프링의 핵심

hmk run dev 2022. 3. 6. 18:10
class OwnerController {
	private OwnerRepository repo = new OwnerRepository();
}

사실 스프링의 핵심 IOC, DI 등등에 대해 포스팅을 여러 번 했지만

내가 쓴 글도 내가 이해하기가 어렵고 정리가 안돼서 이번 글만큼은... 정말 이해하기 쉽게 밥상머리 교육으로 해보고자 포스팅을 해본다...!

 

 

 

IOC (Inversion of Control)

일반적으로 자바의 경우 자기가 사용할 의존성을 자기가 만들어 사용한다.

class OwnerController {
	private OwnerRepository repo = new OwnerRepository();
}

위의 코드에서 OwnerController는 자기가 사용할 의존성을 직접 만들어서 사용한다. ( new OwnerRepository(); )

 

 

그러나 IOC에선 컨트롤러가 의존성을 직접 관리하는 것이 아니라 아래와 같은 코드로 동작하게끔 만든다.

class OwnerController {
	//오너 레포지스트리를 사용하긴 하지만 직접 만들지는 않는다.
	private OwnerRepository repo;
	//생성자를 통해서 받아온다 -> 즉, 오너 컨트롤러가 하는 일이 아님.
	public OwnerController(OwnerRepository repo){
		this.repo = repo;
	}
}

class OwnerControllerTest {
	@Test
	public void create() {
		OwnerRepository repo = new OwnerRepository();
		OwnerController controller = new OwnerController(repo);
	}
}

 

위 코드 주석에도 설명되어 있듯이, OwnerController가 자신이 필요한 의존성인 

OwnerRepository를 직접 new OwnerRepository (); 한 것을 볼 수 있는데 아래 코드를 보면 직접 생성이 아닌 생성의 인자로 OwnerReposiry가 전달되며, 외부주입이 되는 것을 알 수 있다.

 

public OwnerController(OwnerRepository repo){
    this.repo = repo;
}

즉, 의존성이 외부에서 주입 DI( Dependency Injection )이 되는 상황이다. 

 

의존성 주입과 제어의 역전은 너무 어렵게 설명할 필요는 없다.

사실상 의존성 주입과 제어의 역전의 거의 같은 의미로 사용될 수 있으며, 제어의 역전은 의존성 주입을 통해 이루어짐을 확인할 수 있다.

 

그렇다면 이런 제어의 역전의 장점은 무엇이 있을까??

 

우리가 new OwnerRepository(); 를 통해서 인스턴스를 생성했다고 가정해보자. 

그런데 만약? 인스턴스의 생성 비용이 크거나, 굳이 일일이 생성을 하기 귀찮다고 느껴질 때가 있다.

 

스프링 프레임워크는 IOC컨테이너를 통해서, 이러한 인스턴스의 생성을 일괄적으로 진행하고, 라이프 사이클 관리까지

컨테이너에 맡긴다.

 

따라서 인스턴스의 생성 및 관리 주체가 OwnerController가 아닌 외부에서 OwnerRepository를 주입해주는 제 3자 혹은 컨테이너가 되기 때문에 제어의 역전이라고 부르는 것이다.

 

 

그렇다면 스프링에서 의존성 주입은 어떤 방식으로 이루어질까? 일반적으로 스프링 프레임 워크의 의존성 주입은

스프링 IOC 컨테이너에 등록된 빈(Bean)에 해준다.

public class SampleController {
	SampleRepository sampleRepository;
	public SampleController(SampleRepository sampleRepository) {
		this.sampleRepository = sampleRepository;
	}
	//sampleRepository에 기본 값 설정 X = Null pointer Exception이 발생할 수 있다고 생각할 수 있지만, 생성자가 1개 이므로, sampleRepository는 무조껀 생성되어야한다. 따라서, petClinic 프로젝트 또한 안전하다고 볼 수 있다.
	public void doSomething() {
		sampleRepository.save()
	}
}

public class SampleRepository {
	public void save(){
		
	}
}

 

IOC 컨테이너에 등록된 빈들은 어떻게 확인할까?

@Autowired
ApplicationContext applicationContext;

@Test
public void getBean(){
	//등록된 빈들의 이름을 가져온다.
	String s = applicationContext.getBeanDefinitionNames();
	//이름을 활용하여 빈의 정보를 볼 수가 있다.
	applicationContext.getBean(s)

	//두번째 방식으로는 등록된 빈의 타입으로 꺼내오는 방식이다.
	OwnerController bean = applicationContext.getBean(OwnerController.class);
	assertThat(bean).isNotNull();
}

위와 같은 방법으로 확인할 수 있다.

위의 코드에서 IoC 컨테이너 역할을 하는 것이 ApplicationContext이다.

 

ApplicationContext는 BeanFactory라는 컨테이너를 상속받아서 빈팩토리보다 다양한 역할을 할 수 있는 클래스이다.

 

 

 

 

 

출처

https://dailyworker.github.io/spring-triangle/

 

Java Spring Triangle - 자바 스프링 핵심 3대 요소

STEP 1. 제어 역전(IoC, Inversion of Control) STEP 1.1 제어 역전(IoC)이란? STEP 1.2 Bean 등록 방법 STEP 1.3 의존성 주입(DI)란? STEP 2. 관점 지향 프로그래밍(Aspect Oriented Programming) STEP 2.1 관점 지향 프로그래밍(AOP)

dailyworker.github.io

 

Comments