@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를 생략 가능하다.
'💻 Backend > 스프링' 카테고리의 다른 글
타임리프 - 텍스트 쓰는 방법 / Escape - 스프링 MVC 2편 (0) | 2022.01.25 |
---|---|
thymeleaf의 특징 - 스프링 MVC 2편 (0) | 2022.01.25 |
싱글톤 방식의 주의점 (0) | 2022.01.24 |
JPA, JPQL에서 limit 사용하기 (0) | 2022.01.24 |
싱글톤 컨테이너란? (0) | 2022.01.23 |