⭐ 스프링 컨테이너란?
스프링 컨테이너(Spring Container)는 빈(Bean)이라 불리는 자바 객체의 생명 주기(빈의 생성, 관리, 제거 등의 주기)를 관리하며, 생성된 빈에게 추가적인 기능을 제공합니다.
빈이란, 그냥 스프링 컨테이너가 관리하는 객체를 뜻하는데, 이 빈에 대해 더 알고 싶다면 바로 이전글을 보고 오시면 될 거 같습니다!
[Spring] 스프링 빈(Bean)이란? 초보 개발자를 위한 쉬운 설명 🍃
Bean은 콩입니다. ⭐ 빈(Bean)의 유래빈이라고 작명한 이유를 알려면, 자바로 작명한 이유부터 알아야 합니다.자바로 작명한 이유는, 자주 마시는 커피가 인도네시아 자바 섬 커피였기 때문입
blu-blu.tistory.com
아무튼, 스프링 컨테이너가 빈이라는 객체를 생성하고, 그 객체들 사이의 연결을 설정하며, 그 과정을 통해 애플리케이션이 동작하게 됩니다.
이 컨테이너는 흔히 IoC(Inversion of Control, 제어의 역전)라고 불리는 개념을 기반으로 합니다. 전통적인 자바 애플리케이션에서는 개발자가 객체를 생성하고, 객체 간의 의존성을 일일이 관리해야 하지만, 스프링 컨테이너는 이 작업을 자동으로 처리합니다. 이에 관련한 내용은 아래 글에서 훨씬 더 자세히, 이해가기 쉽도록 설명해두었습니다! IoC는 스프링에 있어 매우 중요한 내용이니 꼭 알아두시는 걸 추천합니다!
[Spring] 제어의 역전(IoC)과 의존성 주입(DI) 완벽 이해하기 🍃
🚩 INTRODUCTION제어의 역전(IoC)과 의존성 주입(DI)은 객체지향 프로그래밍에서 코드의 유연성과 유지보수성을 높이는 데 중요한 설계 패턴입니다.이 두 개념은 주로 대규모 애플리케이션에서 코
blu-blu.tistory.com
우리가 '자동차'를 제작한다고 상상해봅시다. 자동차는 엔진, 바퀴, 스티어링 휠 등 여러 부품으로 이루어져 있습니다. 일반적으로는 자동차를 만들 때 각각의 부품을 손수 조립하고 관리해야 하지만, 스프링 컨테이너는 이러한 부품들을 자동으로 연결해주고, 자동차가 잘 작동하도록 조립해주는 역할을 합니다. 즉, 우리는 자동차를 구성하는 부품에 대해 걱정할 필요가 없고, 스프링이 이를 대신 관리해주는 셈입니다.
⭐ 스프링 컨테이너의 역할
✅ 빈(Bean) 관리
빈은 간단히 말해, 스프링 컨테이너에서 관리되는 객체를 의미합니다. 빈은 스프링 설정 파일이나 어노테이션을 통해 등록할 수 있으며, 컨테이너는 등록된 빈의 생명 주기(생성, 초기화, 소멸 등)를 관리합니다.
✅ 의존성 주입(Dependency Injection, DI)
의존성 주입은 스프링 컨테이너의 핵심 기능 중 하나로, 객체들 간의 의존성을 스프링이 자동으로 연결해주는 방식입니다. 이를 통해 개발자는 직접적으로 의존성을 관리하지 않고, 스프링이 알아서 필요한 객체를 주입해주도록 할 수 있습니다.
⭐ 스프링 컨테이너의 종류
스프링 컨테이너는 Bean Factory와 Application Context 두 종류의 인터페이스로 구현되어 있습니다.
둘 다 스프링 컨테이너로서 스프링 빈을 생성하고 관리하는 역할을 하지만, 기능과 사용 목적에서 몇 가지 차이점이 있습니다.
✅ Bean Factory
Bean Factory는 스프링 컨테이너의 최상위 인터페이스이고 그 하위에 여러 가지 구현체가 존재합니다.
가장 기본적인 스프링 컨테이너로, 설정된 빈을 관리하고 의존성을 주입합니다. 그러나 모든 경우에 BeanFactory를 사용하는 것은 아니며, 주로 리소스가 제한적인 상황에서 사용됩니다.
메모리 절약이 중요한 경우나 기본적인 기능만 필요할 때 사용됩니다.
✅ Application Context
BeanFactory를 확장한 컨테이너로, 대부분의 스프링 애플리케이션에서 이 컨테이너를 사용합니다. 이벤트 처리, 국제화, 빈 라이프사이클 관리 등 다양한 부가 기능을 제공합니다.
주로 사용되는 스프링 컨테이너는 Application Context 입니다.
⭐ 스프링 컨테이너에서 의존성을 관리하고 제공하는 방식
스프링 컨테이너에서 의존성 관리는 의존성 주입(Dependency Injection, DI)이라는 개념을 기반으로 이루어집니다. DI는 객체가 다른 객체에 의존할 때, 이를 외부에서 주입해주는 방식입니다. 스프링에서는 주로 세 가지 방식으로 의존성을 주입할 수 있습니다.
✅ 생성자 주입(Constructor Injection)
객체를 생성할 때 의존성을 생성자의 인자로 주입하는 방식입니다. 가장 기본적인 의존성 주입 방법이며, 의존성이 반드시 필요할 경우 생성자 주입을 사용하는 것이 좋습니다.
public class Car {
private Engine engine;
// 생성자를 통해 의존성을 주입
public Car(Engine engine) {
this.engine = engine;
}
}
✅ 세터 주입(Setter Injection)
객체 생성 후, 세터 메서드를 통해 의존성을 주입하는 방식입니다. 선택적인 의존성에 대해 사용할 수 있으며, 의존성이 필요하지 않을 수도 있는 경우에 유용합니다.
public class Car {
private Engine engine;
// 세터를 통해 의존성 주입
public void setEngine(Engine engine) {
this.engine = engine;
}
}
✅ 필드 주입(Field Injection)
필드에 직접적으로 의존성을 주입하는 방식으로, 가장 간단한 방법입니다. 그러나 테스트나 유지보수 측면에서 권장되지 않기 때문에 주로 생성자 주입과 세터 주입이 많이 사용됩니다.
public class Car {
@Autowired
private Engine engine; // 필드 주입
}
⭐ 스프링 컨테이너를 사용하는 이유
객체를 생성하기 위해서는 new 생성자를 사용해야 합니다. 이 때문에 애플리케이션에서는 수많은 객체가 존재하고 서로를 참조하게 돼서 의존성이 높아지게 됩니다.
이는 낮은 결합도와 높은 캡슐화를 지향하는 객체지향 프로그래밍의 핵심과는 먼 방식입니다.
따라서, 객체 간의 의존성을 낮추어(느슨한 결합) 결합도는 낮추고, 높은 캡슐화를 위해 스프링 컨테이너가 사용됩니다.
이렇게 스프링 컨테이너를 사용하는 가장 큰 이유는 유연한 의존성 관리와 객체 간 결합도 감소입니다.
✅ 유연한 의존성 관리
스프링 컨테이너는 객체 간의 의존성을 자동으로 주입해주기 때문에, 애플리케이션이 유연하게 변경될 수 있습니다. 예를 들어, 엔진 객체를 가솔린 엔진에서 전기 엔진으로 바꾸고 싶을 때, 코드의 다른 부분을 수정하지 않고도 엔진만 교체할 수 있습니다.
✅ 객체 간 결합도 감소
스프링 컨테이너를 사용하면 객체들 간의 결합도가 낮아집니다. 이는 객체들이 서로 직접적으로 의존하지 않기 때문에, 더 쉽게 확장하고 유지보수할 수 있는 코드를 작성할 수 있게 합니다.
기존의 방식으로는 새로운 기능이 생기게 되면 변경 사항들을 수작업으로 수정해야 하므로 프로젝트가 커질수록 의존도는 높아질 것이고, 그에 따라 코드의 변경도 많아질 것입니다.
하지만, 스프링 컨테이너를 사용하면 구현 클래스에 있는 의존성을 제거하고 인터페이스에만 의존하도록 설계할 수 있게 됩니다.
🚩 총정리
스프링 컨테이너는 스프링 프레임워크의 핵심 구성 요소로, 객체 관리와 의존성 주입을 통해 애플리케이션의 구조를 단순하게 유지하고, 확장 가능하게 만들어줍니다. 의존성 주입을 이해하고, 스프링 컨테이너를 적절히 사용함으로써 유지보수성이 높은 코드를 작성할 수 있습니다. 스프링 컨테이너를 잘 활용하여 보다 유연하고 강력한 애플리케이션을 개발하기 위해 노력해봅시다!
📌 참고
The IoC Container :: Spring Framework
This chapter covers Spring’s Inversion of Control (IoC) container.
docs.spring.io
'기술 지식 쌓아가기 📚 > Backend 🍔' 카테고리의 다른 글
[Spring] 서블릿(Servlet)에 대해 알려드리겠송! 😼🍃 (3) | 2024.09.18 |
---|---|
[Spring] SpEL(Spring Expression Language)이란? Spring에서 표현식을 다루는 쉬운 방법 알아가기 🍃 (1) | 2024.09.16 |
[Spring] 스프링 빈(Bean)이란? 초보 개발자를 위한 쉬운 설명 🍃 (2) | 2024.09.13 |
[Spring] 제어의 역전(IoC)과 의존성 주입(DI) 완벽 이해하기 🍃 (4) | 2024.09.12 |
[Spring] OOP vs AOP: 효율적인 코드 관리를 위한 소프트웨어 설계 핵심 패러다임 비교 🍃 (4) | 2024.09.09 |