Spring Boot/Spring Core
Spring Bean Scope
gigyesik
2024. 4. 15. 04:35
반응형
들어가며
Spring 프레임워크에서 Bean은 IoC 컨테이너로 관리되는 객체이다.
Spring IoC 컨테이너는 Bean의 생성, 설정, 소멸까지 전반적인 라이프사이클을 관리한다.
Bean의 라이프사이클은 Scope 라는 인자로 관리된다.
Bean Scope
Singleton
Bean Scope의 기본설정. 컨테이너에 의해 단 하나의 인스턴스만 생성하고 모든 요청에 대해 이 인스턴스를 공유하여 사용한다.
Prototype
모든 요청마다 새로운 인스턴스를 생성한다.
Request
Web 어플리케이션에서만 가능한 옵션으로, 모든 HTTP 요청마다 새로운 인스턴스를 생성한다.
Session
request와 비슷하게, 모든 HTTP 세션마다 새로운 인스턴스를 생성한다.
Application, Websocket
Spring ApplicationContext 설정에 따른 scope를 제어한다.
Singleton 과 Prototype 차이 예제
Singleton 구현
public class BeanScope {
public BeanScope() {
System.out.println("Bean Instance Created");
}
}
@Configuration
public class BeanScopeConfiguration {
@Bean
@Scope(value = "singleton")
public BeanScope beanScope() {
return new BeanScope();
}
}
public class BeanScopeApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(BeanScopeConfiguration.class);
ctx.refresh();
BeanScope bs1 = ctx.getBean(BeanScope.class);
System.out.println(bs1.hashCode());
BeanScope bs2 = ctx.getBean(BeanScope.class);
System.out.println(bs2.hashCode());
ctx.close();
}
}
Singleton 결과
Bean Instance Created
1604002113
1604002113
Scope를 prototype으로 변경
@Configuration
public class BeanScopeConfiguration {
@Bean
@Scope(value = "prototype")
public BeanScope beanScope() {
return new BeanScope();
}
}
Prototype 결과
Bean Instance Created
1813187653
Bean Instance Created
1353530305
Scope를 request로 변경하면 에러가 난다
웹 환경이 아니기 때문이다.
@Configuration
public class BeanScopeConfiguration {
@Bean
@Scope(value = "request")
public BeanScope beanScope() {
return new BeanScope();
}
}
Request Scope와 Session Scope
Scope 구현
// Request Scope
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class BeanRequestScope {
private String name = "Request Scope";
public BeanRequestScope() {
System.out.println("Request Scope Constructor Called");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// Session Scope
@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class BeanSessionScope {
private String name = "Session Scope";
public BeanSessionScope() {
System.out.println("SessionScope Constructor Called at " + LocalDateTime.now());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Component 정의
@Component
public class BeanScopeCustomer {
@Autowired
private BeanRequestScope beanRequestScope;
@Autowired
private BeanSessionScope beanSessionScope;
public BeanRequestScope getBeanRequestScope() {
return beanRequestScope;
}
public void setBeanRequestScope(BeanRequestScope beanRequestScope) {
this.beanRequestScope = beanRequestScope;
}
public BeanSessionScope getBeanSessionScope() {
return beanSessionScope;
}
public void setBeanSessionScope(BeanSessionScope beanSessionScope) {
this.beanSessionScope = beanSessionScope;
}
}
Rest Controller
@RestController
public class BeanTestController {
@Autowired
private BeanScopeCustomer beanScopeCustomer;
@RequestMapping("/name/request-scope")
public String helloRequestScope() {
return beanScopeCustomer.getBeanRequestScope().getName();
}
@RequestMapping("/name/session-scope-update")
public String helloSessionScopeUpdate() {
beanScopeCustomer.getBeanSessionScope().setName("Session Scope Updated");
return beanScopeCustomer.getBeanSessionScope().getName();
}
@RequestMapping("/name/session-scope")
public String helloSessionScope() {
return beanScopeCustomer.getBeanSessionScope().getName();
}
}
Session 설정
server:
reactive:
session:
cookie:
max-age: 1
timeout: 1
실행하여 결과 확인하기
- Request Scope는 메서드가 실행될 때마다 새로운 인스턴스를 생성한다.
Request Scope Constructor Called
Request Scope Constructor Called
Request Scope Constructor Called
Request Scope Constructor Called
...
- Session Scope는 생성한 세션에 1개의 인스턴스를 생성하고, 세션이 만료되면 새로운 인스턴스를 생성한다. (현재 설정값 1분)
SessionScope Constructor Called at ..
SessionScope Constructor Called at ..
Resources
반응형