29일차 2024.11.18(Spring 1일차 -IoC, DI)

칙촉·2024년 11월 18일

🎯시작 전 목표

  1. IoC 와 DI의 개념

💻Today I learned

Spring공부를 시작 하기로 한 것은 지난 주 부터지만 일주일간의 방황 끝에 방향을 잡게 되었다.
이런저런 일들이 있기도 했고, 아무것도 모르는 상태에서 배우려니 막막하기도 해서 일단 해보자는 식으로 처음에 시작했다.
GPT에게 임의의 Spring 미니 프로젝트를 만들어 달라 하였고, 그것을 해석해보며 배우려는 생각이었다.
하지만 인생은 뜻대로 되지 않는 것. 예상과는 달리 마치 처음 본 언어를 본 것처럼 아무것도 읽히지 않았고, 해석보단 해독에 가까운 작업이 필요해보였다.
그래서 우선 Spring 프레임워크에 대한 기본 개념과 작동 원리부터 파악해야겟다는 생각이 들어 기본 개념 정리부터 하고 시작하기로 했다.

IoC 와 DI

  • IoC (Inversion of Controll)

    애플리케이션의 의존성 관리 및 실행 흐름을 개발자가 아닌 컨테이너가 책임지는 디자인패턴으로 Spring에서 가장 중요한 개념이며, DI ( Dependency Injection ) 매커니즘과 밀접한 관련이 있다.
    전통적인 프로그래밍에서는 클래스가 직접 필요한 의존성을 생성하거나 관리하지만, IoC에서는 다음이 이루어진다.
  • 의존성 관리:
    객체가 스스로 의존성을 생성하는 대신, 외부에서 객체의 의존성을 주입한다.
  • 제어 주체 변경:
    객체 생성, 초기화, 수명 관리 등 애플리케이션의 주요 제어권이 개발자가 아닌 IoC 컨테이너로 이동한다.

IoC의 본질은 다음과 같은 설계 철학으로, Spring 에서만 사용되는 것은 아니다만 아직은 이 이상 깊게 들어가지는 않기로 했다.

  • 제어권 역전
    -객체 생성과 실행 흐름에 대한 제어권을 애플리케이션 코드가 아닌 외부 시스템이 담당.
    -개발자는 객체의 행위에만 집중
  • 결합도 감소
    -객체간의 강한 결합도는 낮춰 코드 재사용성과 유지보수성을 높임
  • 구조적 유연성
    -애플리케이션의 구조를 유연하게 변경할 수 있음.

IoC 의 동작 과정은 다음과 같지만, 솔직히 개념이 부족해 아직 전부 이해하지는 못했고, 그렇구나 하고 넘어간 뒤 이후 다시 찾아 볼 생각이다.

IoC 컨테이너 동작 과정

  1. 컨테이너 초기화:
    ApplicationContext를 생성하며, 모든 Bean의 정의를 읽어들임.

2.Bean 등록:
@Component, @Bean 어노테이션으로 Bean을 등록.

3.의존성 주입:
주입된 Bean이 다른 Bean과 연결됨.

4.Bean 초기화:
@PostConstruct 또는 InitializingBean을 통해 초기화 작업 수행.

5.Bean 사용:
의존성이 주입된 Bean이 애플리케이션 실행 중 사용됨.

6.컨테이너 종료:
@PreDestroy 또는 DisposableBean을 통해 Bean 정리.

이러한 과정을 통해 동작하는 IoC를 사용하려면 IoC에 대한 의존성을 주입시켜 줄 필요가 있는데, 이 때 필요한 매커니즘이 바로 DI패턴이다.

  • DI (Dependency Injection)

    IoC는 제어권을 컨테이너에 위임하는 개념적인 원칙이라면 DI는 IoC를 구현하는 구체적인 메커니즘이다.
    이렇게 말하면 뭔가 거창해 보이지만 그 실상은 알고 보니 별 게 없었다.
    실제로도 많이 쓰이고 나도 많이 써 본 패턴이었는데, 그저 이름을 모르고 있었을 뿐이었다.
    DI는 직역하면 의존성 주입으로, 쉽게 말하면 진짜로 그냥 의존성을 주입하기만 하면 된다.
    장황히 설명 하는 것 보다 코드로 예시를 보면 다음과 같다.

      public class Service {
        public void doSomething() {
            System.out.println("Service is doing something.");
        }
    }
    
    public class Client {
        private Service service;
    
        public Client(Service service) {
            this.service = service;
        }
    
        public void execute() {
            service.doSomething();
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Service service = new Service();
            Client client = new Client(service); // 의존성 주입
            client.execute();
        }
    }

    그러하다. 이게 끝이다.
    물론 Spring에서는 이런 식으로 쓰지 않고 에노테이션이란 놈을 사용해 더 간단히 의존성을 주입시킬 수 있다고 한다.

profile
강세민

0개의 댓글