synchronized를 메소드에 적용한 것 대비 속도 측면에서 오버헤드를 극적으로 줄일 수 있다
Spring Boot 에서 찾은 Singleton
Spring 에서 모든 bean 은 기본적으로 Singleton 으로 생성되는 것을 보장한다.
Spring Configuration annotation docs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/** * Specify whether {@code @Bean} methods should get proxied in order to enforce * bean lifecycle behavior, e.g. to return shared singleton bean instances even * in case of direct {@code @Bean} method calls in user code. This feature * requires method interception, implemented through a runtime-generated CGLIB * subclass which comes with limitations such as the configuration class and * its methods not being allowed to declare {@code final}. * <p>The default is {@code true}, allowing for 'inter-bean references' via direct * method calls within the configuration class as well as for external calls to * this configuration's {@code @Bean} methods, e.g. from another configuration class. * If this is not needed since each of this particular configuration's {@code @Bean} * methods is self-contained and designed as a plain factory method for container use, * switch this flag to {@code false} in order to avoid CGLIB subclass processing. * <p>Turning off bean method interception effectively processes {@code @Bean} * methods individually like when declared on non-{@code @Configuration} classes, * a.k.a. "@Bean Lite Mode" (see {@link Bean @Bean's javadoc}). It is therefore * behaviorally equivalent to removing the {@code @Configuration} stereotype. * @since 5.2 */
정리해보면 CGLIB 라는 프록시 라이브러리를 사용하는데, Spring 에서 프록시 대상이 되려면 @Bean 같은 어노테이션 적용이 필요하다.
생각해보자
Spring Bean 을 왜 싱글톤으로 유지하는 지 궁금해져서 조금 찾아봤다.
Spring의 기본 철학은 데이터 객체가 아닌 서비스를 작성하는 데 도움이 되도록 설계되었다는 것이다. 따라서, 개발자는 관계형 데이터 객체 또는 도메인 객체같은 POJO 타입의 객체를 Spring 이 관리하는 service, repository, controller 에 전달하여, 효율적으로 관리해주는 것이 그 목적이다.
service, repository, controller 같은 객체들은 상태를 저장할 필요가 없으며, 스레드 세이프하게 동작하기 위해 싱글톤으로 인스턴스가 생성되도록 설계되었다.