본문 바로가기

Programming/Spring

[Spring] Bean Scope와 주의할 점

일반적으로 스프링은 처음 구동될 때 초기에 모든 Bean을 생성하고 인스턴스를 생성한다. 하지만, 매번 다른 객체가 사용되어야 하는 경우에는 Bean의 scope를 변경하면 매번 다른 객체를 생성해 사용할 수 있게 된다.

 

Bean Scope

singleton

기본적으로 다른 설정을 지정하지 않았을 때 지정된다. 애플리케이션을 구동하면 bean마다 하나의 객체가 생성되고 스프링을 통해 bean을 주입받게 된다면 언제나 같은 객체를 참조하게 된다.

 

하나의 객체를 통해 주입하게 되므로 메모리를 절약할 수 있고, 런타임시 성능 최적화에 유리하다는 장점이 존재한다.

하지만, 프로퍼디를 공유하기 때문에 다른 객체에서 값을 변경해도 그대로 참조되어 예상치 않게 값이 변경될 수 있고, 초기에 모든 빈을 생성해야 하기 때문에 구동 시간이 지연된다는 단점이 존재한다.

 

 

 

prototype

매번 다른 객체를 생성해 주입해주는 방법이다. Requst, Session 마다 존재하도록 지정할 수도 있다. 

 

 

사용방법

1. xml

<!-- scope="타입" -->
<bean id="..." scope="singleton"/>
<bean id="..." scope="prototype"/>

 

2. java

// @Scope("타입")
@Scope("prototype")
@Scope("session")

 


 

💡 주의할 점

프로토 타입으로 지정된 빈이 싱글톤 타입의 객체를 참조하는 것은 문제가 되지 않는다.

생성되는 프로토 타입은 매번 다르지만 참조하고 있는 싱글톤 객체는 변화가 없다.

 

하지만, 싱글톤 타입의 빈이 프로토 타입의 빈을 참조하면 문제가 발생한다.

싱글톤으로 생성되면 참조하고 있는 프로토타입도 변하지 않기 때문에 매번 같은 객체를 참조하게 되어 의도한대로 실행이 되지 않게 된다.

 

해결 방법

1. proxyMode

프록시로 감싸지 않고 일반적으로 사용한다면 참조값을 바꿔줄 수 없지만, 프록시를 감싼 객체를 참조하면 이를 해결할 수 있다.

사용방법

@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)

 

 

2. ObjectProvider

@Autowired
private ObjectProvider<Proto> proto;

public Proto getProto() {
    return proto.getIfAvailable();
}

싱글톤 객체에 프로토 타입으로 참조하고자 하는 객체를 ObjectProvider를 사용해 처리할 수도 있다.

하지만, POJO class에 스프링 관련 메소드가 들어가기 때문에 그다지 추천하지는 않는다고 한다....

 

 

 


📚 Reference

[인프런] 스프링 프레임워크 핵심 기술 / 백기선

'Programming > Spring' 카테고리의 다른 글

[Spring] AOP, Spring AOP  (0) 2021.04.30
[Spring] Bean 주입하기 : DI  (0) 2021.04.24
[Spring] Bean을 등록하는 방법  (0) 2021.04.22