Spring DI / IoC
의존성 주입 ( DI / Dependency Injection )
DI ( Dependency Injection ) 란 스프링의 핵심 기능으로써 객체를 직접 생성하지 않고, 외부에서 생성한 객체를 주입해주는 방식이다.
IoC ( Inversion Of Control ) 이란 직역하면 "제어의 역전" 이라는 의미로, 스프링에서는 객체를 개발자가 아닌 스프링 컨테이너를 통해 관리한다.
DI / IoC 를 통해 객체 간 결합도를 낮추고 유연성을 높힐 수 있다.
바로 예제로 알아보자.
위와 같은 구조에서 아래 테스트 코드를 기반으로 DI /IoC 의 유연성을 느껴보자
아래 코드에서 사용하는 showDbmsName() 메서드는 각 DbmsService의 name을 출력하는 메소드이다.
package springboot.diioc.sample;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import springboot.diioc.sample.service.DbmsService;
@SpringBootTest
class SampleApplicationTests {
@Autowired
DbmsService dbmsService;
@Test
void showNameTest() {
dbmsService.showDbmsName();
}
}
위 showNameTest 코드를 통해 어떤 메소드가 호출될까 ?
정답은 DbmsService를 구현한 ADbmsService 혹은 BDbmsService 클래스 중 Spring Container에 등록된 객체의 showDbmsName() 메서드가 호출된다.
만약 ADbmsService의 showDbmsName() 메서드가 호출되었다면, 아래와 같이 코드를 확인할 수 있다.
// AdbmsService
package springboot.diioc.sample.service.impl;
import org.springframework.stereotype.Service;
import springboot.diioc.sample.service.DbmsService;
@Service // Spring Container에 등록
public class ADbmsService implements DbmsService {
private String name = "ADbmsService";
@Override
public void showDbmsName() {
System.out.println(name);
}
}
// BDbmsService
package springboot.diioc.sample.service.impl;
import springboot.diioc.sample.service.DbmsService;
public class BDbmsService implements DbmsService {
private String name = "BDbmsService";
@Override
public void showDbmsName() {
System.out.println(name);
}
}
만약 반대로 BDbmsService의 showDbmsName() 메소드를 호출하고 싶은 경우 다음과 같이 @Service 어노테이션을 BDbmsService로 수정하면 된다.
// AdbmsService
package springboot.diioc.sample.service.impl;
import org.springframework.stereotype.Service;
import springboot.diioc.sample.service.DbmsService;
public class ADbmsService implements DbmsService {
private String name = "ADbmsService";
@Override
public void showDbmsName() {
System.out.println(name);
}
}
// BDbmsService
package springboot.diioc.sample.service.impl;
import springboot.diioc.sample.service.DbmsService;
@Service // Spring Container에 등록
public class BDbmsService implements DbmsService {
private String name = "BDbmsService";
@Override
public void showDbmsName() {
System.out.println(name);
}
}
즉 Spring의 의존성 주입(DI) / 제어의 역전 ( IoC )를 통해 실제 작동하는 코드의 변경 없이 실제 의존하는 객체를 변경할 수 있으며, 이를 통해 코드의 결합도를 낮추며 동시에 유연성을 높힐 수 있다.