Spring - 제어의 역전(IOC - Inversion of Control)

지니·2023년 8월 20일
0

spring

목록 보기
12/13

스프링을 공부하다보면 IOC를 배우는데 이게 뭘까?

1. 제어의 역전(IoC): Inversion of Control

Inversion of Control(IoC)는 소프트웨어 엔지니어링에서 매우 중요한 원칙 중 하나이다.

  • 이 원칙은 프로그램의 흐름 제어가 사용자가 아닌 프레임워크에 의해 수행되는 것을 의미한다.

  • 일반적인 프로그래밍에서, 사용자가 작성한 코드(또는 메인 함수)는 프로그램의 흐름을 제어하며 다양한 함수나 객체를 호출한다. 그러나 IoC 원칙에서는 이 흐름이 역전되어, 사용자 코드를 프레임워크가 호출하게 된다. 이것이 바로 "제어의 역전"이라는 표현이 의미하는 것이다.

  • 이러한 원칙은 보통 프레임워크나 라이브러리를 설계할 때 많이 사용되며, 사용자의 코드를 더 모듈화하고 재사용 가능하며 유연하게 만드는데 도움이 된다.

  • 스프링 프레임워크에서 IoC는 주로 "IoC 컨테이너"라는 형태로 구현된다. IoC 컨테이너는 객체의 생명주기를 관리하고, 의존성 주입(Dependency Injection)을 수행하는 등의 역할을 담당한다.


2. 스프링에서의 IoC

  • 스프링에서는 IoC컨테이너가 이러한 제어의 역전을 담당한다. IoC컨테이너는 빈의 생성, 초기화, 의존성 주입, 생명주기 관리 등을 수행한다.

스프링의 IOC 컨테이너란

  • 스프링 부트에서 IoC(제어의 역전) 컨테이너는 주로 ApplicationContext를 지칭한다. 이 컨테이너는 스프링 빈의 생성, 초기화, 의존성 주입, 생명주기 관리 등을 담당한다.

톰캣과 IoC 컨테이너는 다른 목적을 가진 컴포넌트이다.

  1. IoC 컨테이너 (ApplicationContext)

    • 스프링 어플리케이션에서 객체의 생명주기와 의존성을 관리한다. @Component, @Service, @Repository, @Controller 등의 애노테이션으로 표시된 클래스는 IoC 컨테이너에 의해 자동으로 빈(@Bean)으로 등록되고 관리된다.

    • IoC 컨테이너는 @Autowired나 생성자 주입과 같은 방법을 통해 의존성 주입을 수행한다.

  2. 톰캣(tomcat)

    • 톰캣(tomcat)은 자바 서블릿 컨테이너 및 웹서버이다. 웹 애플리케이션을 호스팅하고, 클라이언트의 요청을 처리한다.

    • 스프링 부트는 내장 톰캣(tomcat)을 포함하고 있어서 별도의 웹 서버 설치 없이 웹 애플리케이션을 실행할 수 있다.

  3. 정리

    • 간단히 말하자면, IoC 컨테이너는 애플리케이션의 객체와 그 객체 간의 관계를 관리하는 반면, 톰캣(tomcat)은 외부로부터의 HTTP 요청을 받아 처리하는 역할을 한다.

코드 예시 - 서비스 인터페이스와 구현체 정의

public interface GreetingService {
    void greet();
}

@Component
public class GreetingServiceImpl implements GreetingService {
    @Override
    public void greet() {
        System.out.println("Hello, Spring IoC!");
    }
}
컴포넌트에서 서비스 사용
@Component
public class MyComponent {

    private final GreetingService greetingService;

    @Autowired
    public MyComponent(GreetingService greetingService) {
        this.greetingService = greetingService;
    }

    public void execute() {
        greetingService.greet(); // Output: Hello, Spring IoC!
    }
}
  • 위의 예시에서 GreetingService는 인터페이스로 정의되어 있으며, GreetingServiceImpl은 그 구현체이다.

  • MyComponentGreetingService에 의존하며(필드에 선언되어 있다.), 이 의존성은 스프링 IoC 컨테이너에 의해 주입된다.

  • 개발자는 GreetingService의 인스턴스를 직접 생성(new를 사용)하거나 관리할 필요가 없으며, 단순히 필요한 의존성을 선언하기만 하면 된다. 이렇게 하면 코드의 결합도가 낮아지고, 다른 구현체로 쉽게 교체할 수 있게 된다.

  • 스프링의 IoC는 객체의 생성과 관리를 프레임워크가 담당하도록 제어의 역전을 실현한다. 이로 인해 개발자는 비즈니스 로직에 집중할 수 있으며, 코드의 유연성과 재사용성이 향상된다.


3. 의존성 주입(Dependency Injection)과 제어의 역전

스프링의 IoC 원칙 중에서도 "의존성 주입(Dependency Injection, DI)"은 중요한 개념이다.

  • 의존성 주입은 특정 객체가 필요로 하는 의존 객체를 외부에서 주입받는 것을 의미한다. 이로 인해 객체 간의 결합도를 낮출 수 있고, 유닛 테스트도 용이해진다.

예를 들어, 데이터베이스 연결을 담당하는 DatabaseConnection 클래스가 있다고 가정해 보자.

  • 이 클래스를 직접 생성하고 관리한다면 다양한 문제점이 발생할 수 있다. 반면 스프링 IoC 컨테이너를 사용하면 이런 문제점을 피할 수 있다.
public interface DatabaseConnection {
    void connect();
}

@Component
public class MySQLDatabaseConnection implements DatabaseConnection {
    @Override
    public void connect() {
        // MySQL에 연결하는 로직
        System.out.println("Connected to MySQL database");
    }
}

@Service
public class UserService {
    
    private final DatabaseConnection databaseConnection;

    @Autowired
    public UserService(DatabaseConnection databaseConnection) {
        this.databaseConnection = databaseConnection;
    }

    public void performAction() {
        databaseConnection.connect();
        // 사용자 관련 작업 수행
    }
}
  • 위 코드에서 UserServiceDatabaseConnection에 의존한다. MySQLDatabaseConnection이라는 구현체는 스프링 IoC 컨테이너에 의해 주입된다.

  • 나중에 다른 데이터베이스로 이전해야 할 경우 DatabaseConnection의 다른 구현체만 작성하고 스프링 설정을 조금 변경하면 된다.


4. IoC와 테스트 용이성

IoC의 또 다른 장점은 테스트 용이성이다.

  • 의존성 주입을 활용하면, 실제 객체 대신에 모의 객체(Mock Object)를 쉽게 주입할 수 있다.
  • 이렇게 되면 유닛 테스트가 간단해지고, 특히 통합 테스트 시 외부 시스템과의 연결 없이 로직만 테스트할 수 있다.
// 테스트 코드
public class UserServiceTest {

    @Test
    public void testPerformAction() {
        DatabaseConnection mockConnection = mock(DatabaseConnection.class);
        UserService userService = new UserService(mockConnection);

        userService.performAction();

        verify(mockConnection).connect();
    }
}
  • 이처럼 스프링의 IoC 기능은 객체지향 프로그래밍의 원칙과 유연한 디자인 패턴을 쉽게 구현할 수 있게 도와준다.
profile
탐구하는 Backend 개발자

0개의 댓글