스프링 빈(빈, Bean)
은 스프링 컨테이너
에 의해 관리되는 자바 객체(컴포넌트)입니다.
이때 자바 객체가 인스턴스화 된 것을 빈
이라고 부르고 이 빈이 스프링 컨테이너에 등록되면 스프링 빈
이라고 부르게 됩니다.
기존에서는 new 연산자를 이용해서 객체를 생성했었는데, 스프링에서는 스프링 빈을 컨테이너에 등록함으로써 객체 생성과 관리 등의 제어를 스프링에게 맡기게 됩니다. (
제어 역전 IoC
)
스프링 컨테이너
는 자바 객체들을 관리하는 스프링의 핵심 컴포넌트입니다.
스프링에서는 자바 객체를 빈(Bean)
이라고 부르는데, 이 빈들의 생명주기를 관리하고 추가 기능들을 제공하는 역할을 하는 것이 스프링 컨테이너
입니다.
스프링 컨테이너는 스프링의 특징 중 하나였던 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, @Service, @Repository, @Controller
어노테이션이 있는 클래스를 탐색하여 해당 어노테이션이 있으면 빈으로 등록.수동 등록은 방금 본 방식입니다. @Configuration, @Bean
을 사용해서 개발자가 스프링 컨테이너에 빈을 직접 등록하는 방식입니다.
위에서 @Bean이 붙은 메소드가 생성자를 return 하는 것이 객체를 반환해서 스프링 컨테이너에 등록하기 위함이었습니다.