Spring과 첫 만남...🫠 IoC에 대해 공부해보자!
객체 생성과 의존성 주입과 같은 과정을 개발자가 직접 하지 않고, 그 제어를 외부(프레임워크, 컨테이너)에 위임하는 것을 의미합니다. 개발자는 객체의 제어를 직접 할 필요가 없으므로 복잡한 요소들을 신경쓰지 않고 비지니스 로직에만 집중할 수 있게 됩니다.
과거에는 개발자들이 직접 코드 안에서 new
키워드를 사용해서 객체를 생성
→ 어떤 객체가 어떤 객체를 사용할 지 의존 관계 설정 필요
OrderService orderService = new OrderService();
PaymentService paymentService = new PaymentService();
orderService.setPaymentService(paymentService);
IoC 를 사용하게 되면 객체 생성과 의존성 주입을 IoC 컨테이너가 대신 수행
@Service
public class OrderService {
//OrderService와 PaymentService는 의존 관계
private final PaymentService paymentService;
@Autowired
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
🔼 코드 실행 과정
⇒ OrderService는 스스로 new PaymentService() 하지 않고도 정상적으로 동작!
객체 간 결합도 감소: 개발자가 직접 new 키워드를 통해 객체를 생성하지 않고 IoC 컨테이너가 객체 생성과 연결을 외부에서 처리해주기 때문에 객체 간 결합이 느슨해집니다.
OrderService
는 PaymentService
라는 추상 타입에만 의존
구체적인 구현체 (ex. kakaoPay
, TossPay
) 에는 의존하지 않음
따라서 구현체가 바뀌어도 (ex. kakaoPay
→ TossPay
) OrderService
수정 필요 X
⇒ 객체지향의 OCP 원칙과도 연결 🔗
OPEN 확장에는 열려있음: 새로운 구현체 추가 및 변경 가능
CLOSED 수정에는 닫혀있음: OrderService는 건들이지 않음
지속가능성 및 확장성: 어플리케이션의 새로운 요구사항이나 기능에도 수정해야 하는 코드를 최소화하고 보다 간단하게 처리할 수 있게 됩니다. 이런 유연성이 지속 가능성을 보장하고 시스템이 커져도 확장성을 확보할 수 있게 해줍니다.
테스트 용이성: 진짜 객체 대신 Mock 객체를 쉽게 주입할 수 있어 테스트가 용이해집니다.
진짜 객체 대신 테스트용 mock 객체 주입 가능
mock 객체: 실제 객체처럼 동작하지만, 테스트 목적에 맞게 단순화, 제어된 동작만 수행하는 객체
→ DB 연결, 외부 API 호출 같은 무거운 동작 없이 빠르게 테스트 가능
PaymentService mockPaymentService = Mockito.mock(PaymentService.class);
OrderService orderService = new OrderService(mockPaymentService);
스프링은 어플리케이션 실행 시 IoC 컨테이너를 만들고 그 안에 관리할 객체 = Bean 등록
→ 일일히 XML이나 @Bean 으로 등록할 수 도 있음 BUT 번거로움
⇒ Component Scan 컴포넌트 스캔 기능
특정 패키지를 탐색하여 @Component 계열 annotaion이 붙은 클래스를 찾아 자동으로 Bean 등록
→ @Component
@Controller
@Service
@Repository
모두 스캔 대상
@Component
: 생성한 class를 Bean 으로 등록할 때 사용하는 가장 기본적인 annotaion
@Controller
: 웹 계층에서의 Controller 역할(ex. HTTP 요청 처리)을 위한 객체@Service
: 비지니스 로직 계층에서 사용 비지니스 로직을 담당하는 서비스 클래스라는 의미@Repository
: 데이터 접근 계층에서 사용하고 DB와 연동하는 코드에 붙임사실 전부 @Component 로 써도 Bean 등록은 됨
하지만 가독성을 향상시키고, 부가 기능을 적용하기 위해 상황에 맞는 annotation 선택