💻 Backend/스프링

@Configuration과 싱글톤

미미누 2022. 1. 24. 21:14
@Configuration
public class AppConfig {
 @Bean
 public MemberService memberService() {
 return new MemberServiceImpl(memberRepository());
 }
 @Bean
 public OrderService orderService() {
 return new OrderServiceImpl(
 memberRepository(),
 discountPolicy());
 }
 @Bean
 public MemberRepository memberRepository() {
 return new MemoryMemberRepository();
 }
 ...
}

위 코드에서 각각 memberService 빈과 orderService 빈을 만드는 코드에서

new MemoryMemberRepository를 호출하면서, 여러개의 객체를 생성하여 

싱글톤을 깨지는 것처럼 보인다. 

 

하지만 위에서 @Configuration 어노테이션을 통해서, 하나의 memberRepository를 공유하여

사용하여, 싱글톤을 유지하게 된다.

 

@Configuration 어노테이션을 붙으면, CGLIB라는 바이트코드 조작 라이브러리를 사용하여

클래스를 상속받은 임의의 다른 클래스를 만들고, 그 다른 클래스를 스프링 빈으로 등록하게 된다.


 

AppConfig.class 를 @Configuration을 이용하여 스프링 빈에 등록하면, AppConfig 자체가

등록되는 것이 아니라, AppConfig를 상속받은 AppConfig@CGLIB 클래스가 스프링 빈에 등록된다.

 

@Bean이 붙은 메서드마다 이미 스프링 빈이 존재하면 존재하는 빈을 반환하고,

스프링 빈이 없으면 생성해서 스프링 빈으로 등록하고 반환하는 코드가 동적으로 만들어진다.

 

@Configuration 말고도, @Autowired 필드 의존관계 주입이나, 생성자 의존관계 주입으로

스프링 빈에 등록하여 싱글톤을 유지하는 방법이 있다.


[필드 의존관계 주입]

@Service 
public class UserServiceImpl implements UserService { 
	@Autowired private UserRepository userRepository; 
	@Autowired private MemberService memberService; 
}

이런식으로 필드에 @Autowired를 붙여, new UserRepository 객체를 생성할때, 객체를 필드에

주입하여 한 번만 사용되도록 만들어준다.

 

[생성자 의존관계 주입]

 

위 사진은 생성자 의존관계 주입방법이다.  

생성자의 호출 시점에 1회 호출 되는 것이 보장된다.

주입받은 객체가 변하지 않거나, 반드시 객체의 주입이 필요한 경우에 강제하기 위해 사용된다고 한다.

생성자 위에 @AutoWired를 생략 가능하다.

 

 

참고: https://mangkyu.tistory.com/125

 

[Spring] 다양한 의존성 주입 방법과 생성자 주입을 사용해야 하는 이유 - (2/2)

Spring 프레임워크의 핵심 기술 중 하나가 바로 DI(Dependency Injection, 의존성 주입)이다. Spring 프레임워크와 같은 DI 프레임워크를 이용하면 다양한 의존성 주입을 이용하는 방법이 ..

mangkyu.tistory.com