[Spring] 스프링 빈과 스프링 컨테이너

Bam·2024년 4월 16일
0

Spring

목록 보기
8/48
post-thumbnail

스프링 빈

스프링 빈(빈, Bean)스프링 컨테이너에 의해 관리되는 자바 객체(컴포넌트)입니다.

이때 자바 객체가 인스턴스화 된 것을 이라고 부르고 이 빈이 스프링 컨테이너에 등록되면 스프링 빈이라고 부르게 됩니다.

기존에서는 new 연산자를 이용해서 객체를 생성했었는데, 스프링에서는 스프링 빈을 컨테이너에 등록함으로써 객체 생성과 관리 등의 제어를 스프링에게 맡기게 됩니다. (제어 역전 IoC)


스프링 컨테이너

스프링 컨테이너는 자바 객체들을 관리하는 스프링의 핵심 컴포넌트입니다.

스프링에서는 자바 객체를 빈(Bean)이라고 부르는데, 이 빈들의 생명주기를 관리하고 추가 기능들을 제공하는 역할을 하는 것이 스프링 컨테이너입니다.

IoC와 스프링 컨테이너

스프링 컨테이너는 스프링의 특징 중 하나였던 IoC(제어 반전, Inversion of Control)를 수행합니다.

제어 반전은 개발자가 아닌 다른 매체(여기서는 스프링 컨테이너)가 객체 관리에 대한 권한을 갖는 것을 의미합니다.

스프링 컨테이너는 ApplicationContext 인터페이스를 통해서 구현되어 있습니다.

BeanFactory라는 스프링 컨테이너도 있으나 ApplicationContext가 BeanFactory의 기능을 더욱 발전시킨 형태이기 때문에 ApplicationContext가 더 많이 사용됩니다. 아래 그래프를 보시면 ApplicationContext가 BeanFactory를 포함한 다른 인터페이스들을 다중 상속함을 알 수 있습니다.

ApplicationContext를 이용해서 단순히 빈 관리 뿐만 아니라 메세지, 이벤트, 리소스에 대한 기능까지 포괄적으로 다루게 됩니다.


스프링 컨테이너는 스프링 빈을 등록할 때 싱글톤 패턴을 이용해서 등록을 합니다. 싱글톤 패턴은 단 하나의 인스턴스만 생성하도록 보장하는 디자인 패턴입니다.

따라서 동일한 스프링 빈은 무조건 같은 인스턴스를 다룬다고 할 수 있습니다. (= 빈 요청시 새로 생성하지 않고 컨테이너에 존재하는 빈을 return)


스프링 컨테이너 생성과 스프링 빈 등록

스프링 컨테이너 생성

다음 코드는 어노테이션을 이용해서 스프링 컨테이너를 생성한 예시입니다.

//컨테이너 생성 + 구성 설정으로 AppConfig.class를 사용
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
//AppConfig.java
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
}

@Configuration은 이 어노테이션이 붙은 클래가 빈의 메타 정보를 가진 클래스라고 스프링 컨테이너에게 알려주는 어노테이션입니다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
}

스프링 컨테이너에 스프링 빈 등록

다음 두 코드는 빈이 될 대상인 Controller와 Service입니다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
}
import org.springframework.stereotype.Service;

@Service
public class UserService {
    public UserService() {}
}

위 두 클래스를 빈으로써 스프링 컨테이너에 등록하는 방법은 다음과 같습니다.

@Configuration
public class AppConfig {
    @Bean
    public UserService userService() {
        return new UserService();
    }

    @Bean
    public UserController userController() {
        return new UserController(userService());
    }
}

Controller의 @Autowired는 이 생성자로 만들어지는 인스턴스는 UserService와 의존 관계를 갖는다는 것을 알리는 의미입니다. @Autowired는 의존 관계의 인스턴스가 스프링 컨테이너에 빈으로 등록되어야 동작합니다.

자동 등록과 수동 등록

스프링 컨테이너에 빈을 등록하는 방식에는 자동 방식과 수동 방식이 있습니다.

자동 등록

자동 등록은 별다른 설정 없이 스프링이 알아서 빈들을 찾아서 등록해주는 방식입니다. 이 방식에는 두 가지 어노테이션이 사용됩니다.

  • @Component: 클래스에서 선언. 런타임때에 스프링이 컴포넌트 스캔을 통해 자동으로 빈을 찾아서 등록.
  • @ComponentScan: 사용된 클래스의 패키지와 하위 패키지의 @Component, @Service, @Repository, @Controller 어노테이션이 있는 클래스를 탐색하여 해당 어노테이션이 있으면 빈으로 등록.

수동 등록

수동 등록은 방금 본 방식입니다. @Configuration, @Bean을 사용해서 개발자가 스프링 컨테이너에 빈을 직접 등록하는 방식입니다.

  • @Configuration: 구성 정보 등록
  • @Bean: 어노테이션이 붙은 메소드를 호출하여 반환되는 객체를 스프링 컨테이너에 등록

위에서 @Bean이 붙은 메소드가 생성자를 return 하는 것이 객체를 반환해서 스프링 컨테이너에 등록하기 위함이었습니다.

0개의 댓글