Spring컨테이너에서 관리하는 객체인 Bean이 무엇인지 알아보고 Bean Scope와 생성방식, 스프링이 Bean을 어떻게 관리하는지에 대해 알아보자.
1. Bean이란?
Bean은 Spring IoC Container가 관리하는 자바 객체를 말한다. Spring IoC Container에 의해 인스턴스화, 생성, 관리되며 컨테이너가 소멸할 때 함께 소멸된다. 토비의 스프링에는 '빈은 스프링이 IoC 방식으로 관 리하는 오브젝트로, 스프링이 직접 그 생성과 제어를 담당하는 오브젝트만을 빈이라고 부른다.'라고 정리되어 있다.
Spring Container는 Bean을 Singleton으로 관리한다. 따라서 동일한 여러 개의 빈을 생성해서 getBean()으로 가져온다면, 언제나 같은 빈을 반환한다.
* Singleton 패턴이란? 객체를 최초 한 번만 메모리에 할당해두고 그 다음부터는 생성해두고 이후부터는 생성된 객체를 참조해서 사용하는 것을 말한다. 하지만 반드시 단 하나인 것은 아니고, 제한된 인스턴스의 개수를 사용하나 주로 하나만 존재하도록 강제한다.
ApplicationContext context = new AnnotationConfigApplicationContext(DaoFactory.class);
UserDao dao1 = context.getBean("userDao", UserDao.class);
UserDao dao2 = context.getBean("userDao", UserDao.class);
System.out.println(dao1); // springbook.dao.UserDaoo@ee22f7
System.out.println(dao2); // springbook.dao.UserDaoo@ee22f7
참고로, 스프링에서 ApplicationContext는 IoC Container임과 동시에 싱글톤을 저장하고 관리하는 *싱글톤 레지스트리(Singleton Registry)이다.
잠시 짚고 넘어가는, 서버 애플리케이션과 싱글톤 - 토비의 스프링 참조
스프링은 기본적으로 내부에서 생성하는 Bean을 모두 싱글톤으로 생성해서 관리한다.
그 이유는 스프링이 주로 적용되는 대상이 자바 엔터프라이즈 기술을 사용하는 서버환경이기 때문이다. 스프링이 처음 설계되었던 대규모 엔터프라이즈 서버환경은 초당 최대 수십, 수백 개의 요청을 받아 처리하는 높은 성능이 요구되는 환경이었다. 이 때마다 매번 새로운 오브젝트를 생성해서 사용할 경우 아무리 GC의 성능이 좋아졌다고 해도, 서버가 감당하기 힘든 부하가 걸릴 것이다.
따라서, 서비스 오브젝트라는 개념을 사용해왔는데 서블릿이 바로 자바 엔터프라이즈 기술의 기본이 되는 서비스 오브젝트라고 할 수 있다. 서블릿은 대부분의 멀티스레드 환경에서 싱글톤으로 동작하며 여러 스레드에서 초기에 생성된 단 하나의 오브젝트를 공유하여 사용한다.
* 싱글톤 레지스트리(Singleton Registry)
스프링은 서버 환경에서 싱글톤이 만들어져 서비스 오브젝트 방식으로 사용되는 것은 적극 지지하지만, 자바의 기본적 싱글톤 패턴 구현 방식은 여러 단점이 있다. 따라서 스프링은 직접 싱글톤 형태의 오브젝트를 생성하고 관리하는 기능을 제공하는데 이를 싱글톤 레지스트리라고 한다. 다시 말하면 스프링 컨테이너는 싱글톤을 생성하고, 관리하고, 공급하는 싱글톤 관리 컨테이너이기도 하다.
기본적으로 싱글톤은 static과 private을 이용하여 만들어지는데 싱글톤 레지스트리는 이를 사용하는 비정상적 클래스가 아니라 평범한 자바 클래스라도 IoC 컨테이너를 사용하여 제어권을 컨테이너에게 넘기면 싱글톤 방식으로 만들어져 관리될 수 있다. 따라서 public으로 생성된 오브젝트라도 싱글톤으로 사용될 수 있다.
싱글톤과 오브젝트의 상태
스프링에서 오브젝트가 싱글톤으로 관리되기 때문에 주의해야 할 점이 몇 가지 있다. 싱글톤 객체 내에 설정정보들이 저장되어 있고 여러 스레드들이 이를 동시에 접근하여 사용한다면 문제가 발생할 것이다. 따라서 개별적으로 변경되는 정보는 로컬 변수로 사용하거나 파라미터로 전달되어 사용되어야 한다.
2. Bean Scope란?
빈 스코프(Bean Scope)란 Bean이 생성되고 존재하고 적용되는 범위를 말한다. 스프링 빈의 기본 스코프는 싱글톤 스코프이다. 컨테이너 내에 한 개의 오브젝트만 생성되고 스프링 컨테이너가 종료될 때까지 계속 유지된다.
경우에 따라 다른 스코프가 될 수 있으며, 대표적으로 프로토타입 스코프는 싱글톤과 달리 컨테이너에 빈을 요청할 때마다 매번 새로운 오브젝트를 생성한다. 이 밖에도 HTTP 요청이 생길 때마다 생성되는 요청 스코프(Request Scope)나, 웹의 세션과 스코프가 유사한 세션 스코프(Session Scope) 등이 있다.
Scope를 지정해주기 위해서는 @Component를 이용하여 빈을 등록할 때 @Scope 어노테이션을 이용하여 직접 지정해주는 것이다.
@Component @Scope(value="singleton")
@Component @Scope(value="prototype")
@Component @Scope(value="request")
@Component @Scope(value="session")
@Component @Scope(value="application")
...
3. Bean 생성 방식
1) Component Scanning
가장 편하게 사용할 수 있는 Bean 등록 방법이다. 스프링 프로젝트를 해보았던 사람이라면 @Controller, @Service, @Component 등의 어노테이션을 한 번쯤 보았을 것이다. Spring에서는 @Component 어노테이션이 있을 경우 자동으로 Spring Bean으로 등록해준다.
// 아래 어노테이션들은 모두 @Component에 해당된다. 특정 역할을 명확히 구분하기 위해 구분하여 사용한다.
@Configuration : Spring Container의 설정을 담당하거나 Bean을 생성한다.
@Controller : 외부로부터의 요청을 받는 클래스이다.
@Service : 비즈니스 로직을 담당하는 클래스이다.
@Repository : DB와 연동하는 역할을 담당하는 클래스이다.
또한 @ComponentScan 어노테이션을 사용하면 해당 클래스와 같은 Level의 패키지의 하위 클래스들에 대해 컴포넌트 스캔을 진행하며 빈을 등록한다.
2) @Configuration
Configuration 설정 파일을 생성하여 @Configuration 어노테이션을 추가해주면 Spring Container에 대한 설정 뿐만 아니라 Bean을 등록해줄 수 있다. 사용할 Bean을 리턴해주는 메소드를 생성해주면 된다.
@Configuration // 애플리케이션 컨텍스트 또는 빈 팩토리가 사용할 설정 정보라는 표시
public class DaoFactory {
@Bean // 오브젝트 생성을 담당하는 IoC용 메소드라는 표시
public UserDao userDao() {
return new UserDao(connectionMaker());
}
}
3) XML 파일
간단한 어노테이션을 이용하지 않고 resources/application.xml 파일에 직접 빈을 등록해줄 수도 있다.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="springbook.dao.UserDao" />
</beans>
참고
- 도서 : 토비의 스프링 3.1 Vol.1
- 홈페이지 : https://velog.io/@probsno/Bean-%EC%8A%A4%EC%BD%94%ED%94%84%EB%9E%80
'백엔드' 카테고리의 다른 글
[Spring] IoC와 DI - 2. IoC(제어의 역전)이란? (토비의 스프링) (0) | 2021.09.26 |
---|---|
[Spring] Bean Factory와 Application Context (0) | 2021.09.25 |
[Spring] IoC와 DI - 1. 오브젝트와 의존관계(토비의 스프링) (0) | 2021.09.21 |
[Network] Syn Flooding이란? (0) | 2021.09.21 |
[Network] TCP와 UDP, HTTP1,2,3, HOLB란? (0) | 2021.09.19 |
댓글