///////
Search
🪴

Configuration은 어떻게 Bean을 등록하고 관리할까요? (Singleton을 지키는 매커니즘은?)

@Configuration public class AppConfig { @Bean public StationRepository stationRepository() { return new JdbcStationRepository(); } @Bean public StationService stationService() { return new StationServiceImpl(stationRepository()); } @Bean public LineService lineService() { return new LineServiceImpl(stationRepository(), lineRepository()); } // ... }
Java
복사
위 코드를 보면, stationRepository() 가 2번 사용되는데, 하나의 인스턴스로 주입된다.
@Configuration 어노테이션이 붙은 클래스는 CGLIB을 이용하여 우리가 만든 클래스를 상속받아 임의의 클래스를 만들어주고,
CGLIB : 바이트 코드 조작 라이브러리. 런타임에 동적으로 자바 클래스의 프록시를 생성해주는 기능을 제공.
그 클래스가 빈으로 등록되는 것이다. 이 조작된 빈이 싱글톤을 보장해준다.
위 AppConfig 클래스는 @Configuration 어노테이션이 붙어있어 스프링 빈으로 등록된다.
bean = class hello.core.AppConfig$$EnhancerBySpringCGLIB$$bd479d70
Java
복사
클래스 정보를 출력하면 위 처럼 class hello.core.AppConfig 뒤에 $$EnhancerBySpringCGLIB$$bd479d70 이런 부가 정보가 붙어있다.
위 그림 처럼 @Configuration 어노테이션이 붙으면,
CGLIB라는 바이트코드 조작 라이브러리를 사용해서 Appconfig 클래스를 상속한 임의의 다른 클래스를 만든 뒤, 그 클래스를 빈으로 등록한다.
@Bean public MemberRepository memberRepository() { if (memoryMemberRepository가 이미 스프링 컨테이너에 등록되어 있으면?) { return 스프링 컨테이너에서 찾아서 반환; } else { // 스프링 컨테이너에 없으면 기존 로직을 호출해서 MemoryMemberRepository를 생성하고 // 스프링 컨테이너에 등록 return 반환 } }
Java
복사
CGLIB의 내부 기술을 사용하므로 매우 복잡한데, 위와 같은 원리로 싱글톤을 보장한다.
캐싱 기능과 유사한 방법이라고 생각하면 된다!