코딩/자바

[Spring] IOC/DI, 싱글톤 패턴

yoney 2025. 2. 5. 10:01

[ 목차 ]


    IOC(제어의 역전, Inversion Of Control)

    객체 관리를 개발자가 아닌 컨테이너가 담당하는 것을 말한다.


    DI(의존성 주입, Dependency Injection)

    Spring이 객체 간의 의존성을 자동으로 주입해주는 것을 말한다. 객체를 생성할 필요 없이 Spring이 주입해주는 방식.


    의존성 주입 방법

    • @Autowired 는 의존성을 자동으로 주입할 때 사용하는 Annotation 이다.
      • 기본적으로 주입할 대상이 없으면 오류가 발생한다.(required = true)
    • 생성자 주입
      • 대부분의 framework가 생성자 주입 방식을 권장한다.
      • 생성자를 통해 의존성을 주입하는 방법.
      • 최초에 한번 생성된 후 값이 수정되지 못한다.[불변, 필수]
      • 생성자가 하나인 경우 생략이 가능하다.
    // 생성자 주입 방식
    @Component
    public class MyApp {
    		// 필드에 final 키워드 필수! 무조건 값이 있도록 만들어준다.(필수)
        private final MyService myService;
    
    		// 생성자를 통해 의존성 주입, 생략 가능
        @Autowired
        public MyApp(MyService myService) {
            this.myService = myService;
        }

     

    • Setter 주입
      • Setter 메서드를 통해 의존성을 주입하는 방법.
      • 선택하거나, 변경 가능한 의존관계에 사용한다.(생성자 주입은 필수 값)
    // MyService가 Spring Bean으로 등록되지 않은 경우에도 주입이 가능하다.
    @Autowired(required = false)
    public void setMyService(MyService myService) {
        this.myService = myService;
    }
    
    // 실행 도중 인스턴스를 바꾸고자 하는 경우
    // setMyService(); 메서드를 외부에서 호출하면 된다.(이런 경우는 거의 없음)

     

    • 필드 주입
      • 필드에 직접적으로 주입하는 방법 (가장 추천되지 않음).
    @Component
    public class MyApp {
    
        @Autowired
        private MyService myService;  // 필드에 직접 주입
    
        public void run() {
            myService.doSomething();
        }
        
    }

    @RequiredArgsConstructor

    실제 Web Application을 개발하면 대부분이 불변 객체이고 생성자 주입 방식을 선택하게 된다. 이런 반복되는 코드를 편안하게 작성하기 위해 Lombok에서 제공하는 Annotation 이다.

    • final 필드를 모아서 생성자를 자동으로 만들어 주는 역할
    • 생성자를 하나 만들고 @Autowired를 사용한 코드와 똑같이 동작한다.

    싱글톤 패턴

    클래스의 인스턴스가 오직 하나만 생성되도록 보장하는 디자인 패턴이다.


    싱글톤 패턴의 등장

    Web Application은 불특정 다수의 고객이 동시에 많은 요청을 보낸다.

    • 요청을 할 때 마다 객체를 새로 생성되고 처리가 완료되면 소멸된다.
    • 메모리 낭비가 아주 심하다.


    싱글톤 패턴 적용

    객체 인스턴스가 하나만 생성되고 생성된 인스턴스만 사용하도록 만든다.

    • 객체가 한번만 생성되어 리소스를 절약할 수 있다.


    싱글톤 패턴 주의점

    싱글톤 패턴의 객체는 상태를 유지(stateful)하면 안된다. 데이터의 불일치나 동시성 문제가 발생할 수 있기 때문에 무상태(stateless)여야하고 특정 클라이언트에 의존적인 필드가 있거나 변경할 수 있으면 안된다.