[LG CNS AM Inspire Camp 1기] Spring (1) - 스프링 컨테이너 & Bean 기본

정성엽·2025년 1월 21일
1

LG CNS AM Inspire 1기

목록 보기
30/53

INTRO

이전에 스프링 부트를 사용해서 간단하게 백엔드 프로젝트를 진행해본적이 있다.

하지만, 그 당시에는 너무 급하게 공부를 시작했기에 기본기가 제대로 정립되지 않은 상태로 개발을 진행했던 기억이 있다.

이번 LG CNS AM Inspire Camp에서 강의를 수강하며 백엔드 기본부터 탄탄하게 쌓아올릴 예정이다.

이번 포스팅에서는 스프링의 개념과 빈(Bean), 그리고 의존성 주입(DI)을 살펴보자 👀


1. Spring이란?

스프링은 자바 기반 프레임워크이다.
기존에 자바 기반으로 개발하고 사용하던 클래스를 Bean이라는 개념을 통해 유지 보수를 수행한다.

이 과정에서 스프링은 여러가지 개념을 도입하고 있는데 주요 개념을 살펴보자

💡 스프링 컨테이너

스프링 컨테이너는 Bean을 생성하고 관리하는 핵심 요소이다.

개발자가 작성한 클래스들을 Bean으로 등록하고, 이러한 Bean들의 생명주기를 관리하면서 애플리케이션의 동작을 제어하는 중추 역할을 수행한다.

그렇다면 스프링 컨테이너는 어떻게 생성할까?

다음 코드를 살펴보자

Sample Code 1

private static ApplicationContext ctx = new AnnotationConfigApplicationContext(AppCtx.class);

컨테이너는 이처럼 ApplicationContext 라는 인터페이스를 사용해서 생성할 수 있다.

예제 코드와 같이 ApplicationContext를 상속받은 여러가지 구현체를 통해 인스턴스를 생성할 수 있으며, 매개변수로는 @Configuration 어노테이션이 붙은 AppCtx.class라는 설정 파일을 넘겨주고 있다.

AnnotationConfigApplicationContext의 구현을 한번 살펴보자

사진과 같이 오버로딩을 통해 여러 방식으로 매개변수를 받을 수 있다.

우리는 위 오버로딩된 생성자들을 통해 다음과 같은 방식으로도 컨테이너를 생성할 수 있다

Sample Code 2

// 빈 컨테이너 생성
ApplicationContext ctx = new AnnotationConfigApplicationContext();

// 특정 패키지를 스캔하여 생성
ApplicationContext ctx = new AnnotationConfigApplicationContext("com.example");

하지만 이렇게 설정 정보 없이 컨테이너를 생성하는 것은 추천하지 않는다.

빈 설정을 한 곳에서 관리하기 어렵고, 빈들 간의 의존관계를 파악하기 힘들어지기 때문이다.

따라서 @Configuration 어노테이션이 붙은 설정 클래스를 통해 명시적으로 빈 설정을 관리하는 것이 좋다!

그렇다면 빈은 뭘 의미할까?


2. Bean

스프링에서 빈(Bean)은 스프링 컨테이너가 관리하는 자바 객체를 의미한다.

스프링은 기본적으로 한 개의 @Bean 어노테이션에 대하여 한 개의 빈 객체를 생성하며, 이를 싱글톤 방식으로 관리한다.

💡 싱글톤 패턴

빈은 기본적으로 싱글톤 객체이다.

여기서 싱글톤 객체란 오직 하나의 인스턴스만을 갖는 객체를 의미한다.

싱글톤 패턴의 간단한 구현은 다음과 같다

Sample Code

class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

패턴을 구현하는 주요 키워드는 다음과 같다.

싱글톤 패턴의 주요 특징

1. private 생성자
외부에서 객체 생성을 막기 위해 생성자를 private으로 선언한다.

2. private static 인스턴스
클래스 내부에서 자신의 객체를 static으로 생성하여 관리한다.

3. public static getInstance()
외부에서 인스턴스에 접근할 수 있는 유일한 메서드로, 생성된 객체를 반환한다.

이를 통해 애플리케이션 전체에서 단 하나의 인스턴스만 존재하도록 보장한다.

우리는 Bean이 기본적으로는 오직 하나의 Bean만 존재한다는 것을 기억하자!

💡 Bean의 특성

스프링은 기본적으로 한 개의 @Bean 어노테이션에 대하여 한 개의 빈 객체를 생성한다.

일반 자바 객체와 빈의 차이를 코드로 살펴보자

Sample Code - 일반 자바 객체

Greeter g1 = new Greeter();
Greeter g2 = new Greeter();

System.out.println("g1 == g2 : " + (g1 == g2)); // False

일반 자바 객체는 각각의 인스턴스가 서로 다른 주소를 갖는다.

각 인스턴스가 생성되면 객체의 생성은 힙 메모리에서 진행되고 인스턴스는 생성된 각 객체의 힙 메모리 주소를 가르키기 때문에 False를 반환한다.

Sample Code - 스프링 빈의 경우

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppContext.class);
Greeter g3 = ctx.getBean("greeter", Greeter.class);
Greeter g4 = ctx.getBean("greeter", Greeter.class);

System.out.println("g3 == g4 : " + (g3 == g4)); // True

반면 빈으로 생성된 객체는 싱글톤 패턴이므로 동일한 주소를 가르킨다는 것을 간단한 코드를 통해 확인할 수 있다!


OUTRO

이번 포스팅을 통해서 스프링이 기존 자바와 다르게 어떤 방식으로 객체를 관리하는지를 살펴봤다.

사실 컨테이너와 빈 사이에서는 수많은 상호작용이 존재한다.

생명주기 관리 및 스코프, 그리고 의존성 주입까지 모두 정리하려고 했으나 분량 조절에 실패하여 다음 포스팅으로 넘기고자 한다

간단하게 스프링 컨테이너는 빈을 통해 객체 인스턴스를 관리하고,빈은 기본적으로 싱글톤의 특징을 갖는다는 것만 알아두자 👊

profile
코린이

0개의 댓글

관련 채용 정보