요깨비's LAB

[Spring Boot, Back-End] 번외. 의존성 주입 본문

웹 개발/스프링 부트 프로젝트(레스토랑 예약)

[Spring Boot, Back-End] 번외. 의존성 주입

요깨비 2020. 1. 7. 17:04

1. 의존 관계: 둘 이상의 객체가 서로 협력하는 방법

A는 B에 의존 = A는 B를 사용 (하지만 이것은 문제가 됨!) -> B의 변화가 A에 영향을 끼치기 때문

조금 더 구체적인 사례를 위해 저희가 지금 개발하고 있는 프로젝트에 비유하겠습니다.
저희는 현재 RestaurantController를 개발했습니다. RestaurantController는 RestaurantRepository를
사용합니다. 즉, Controller는 Repository에 의존하고 있다는 뜻이기도 합니다.

@RestController
public class RestaurantController {
	private RestaurantRepository repository = new RestaurantRepository(); // 직접 생성
    
    ...
}

이 코드를 보면 컨트롤러가 직접 Repository를 생성하여 사용하고 있습니다. 즉, 객체를 생성하는 책임을 Controller가
가지고 있다는 뜻이죠. 그리고 이렇게 만들어진 Repository를 컨트롤러가 직접 자신의 멤버 변수에 연결을 지어주죠.

객체를 만들어주고 연결해주는 반복적인 작업을 우리가 Repository를 따로 분리한 것처럼 이것도 구현할 수 있겠죠? 
스프링은 이 기능을 지원해주고 있습니다. 이것을 Spring IoC Container라고 부릅니다. 스프링을 배울때 항상 배우는
DI(Dependedy Injection)는 객체간의 의존관계를 스프링이 직접 관리를 해주는 것을 의미합니다.(우리가 직접 의존 기능을 구현하는 의미도 포함입니다. 스프링을 사용하기 때문에 보통 이렇게 의미하는걸로 이해합시다~)

* 중요..
@Component와 @Autowired를 적용하여 테스트를 수행했을때 Bean을 찾을 수 없다는 에러가 계속 뜰겁니다. 
스프링 테스트를 수행할 때 저장소를 이용하거나 그 외에 몇가지 이유로 빈을 찾을 수 없도록 막은게 있는데요
이거를 해결하기 위해서는 테스트 수행 코드에 @SpyBean 어노테이션을 이용해 직접 의존성을 주입하면 됩니다.

@RunWith(SpringRunner.class)
@WebMvcTest(RestaurantController.class) // Restaurant 컨트롤러를 테스트하겠다는 어노테이션
/*
 * 중요! @webMvcTest는 제대로된 저장소를 사용할 수 없기 때문에 테스트를 하기 위해서는
 * 직접 의존성을 주입해줘야 한다. @SpyBean 이용!!!
 */
public class RestaurantControllerTest {
	@Autowired
	private MockMvc mvc;
	
	@SpyBean
	private RestaurantRepository restaurantRepository;

	...
}


이렇듯 의존성 주입을 통해 우리는 사용하려는 객체를 다양하게 변경할 수 있습니다. 추상화를 통해 인터페이스화 하고, 
해당 인터페이스를 구현하는 다양한 객체를 유연하게 바꿔가면서 사용할 수 있습니다.

1. 기존 RestaurantRepository를 interface로 바꾸고 메서드만 명시해줍니다.
2. RestaurantRepositoryImpl 클래스를 만들어 인터페이스를 구현합니다. 
3. Test 코드로 가서 @SpyBean(RestaurantRepositoryImpl.class)로 변경해줍니다.

이렇게 해주면 RestaurantRepository를 구현하는 다양한 Repo를 유연하게 사용할 수 있습니다.

Comments