싱글톤 - 인스턴스가 한개임을 보장하는 객체지향 설계 패턴
컨테이너 - 스프링 프레임워크가 객체를 담아놓는 저장소
객체 생성에 소요되는 시간을 절약하고 메모리 낭비를 막는다.
서버 프로그램은 많은 이용자를 대상으로 운영된다. 모든 유저의 요청에 새로운 객체가 생성된다면 프로그램이 느려질 것이다. 또한 서버 컴퓨터의 메모리 사용량이 많아진다.
스프링의 싱글톤 컨테이너는 이 문제를 모두 해결한다.
객체 하나를 공유해서 사용하기 때문에 변경 가능한 인스턴스 변수(상태)를 사용하도록 프로그램을 작성할 경우 예기치 않은 결과를 가져올 수 있다.
이를 스프링이 제한하지 않기 때문에 개발자가 싱글턴의 특징을 이해하고 조심해야 한다.
@Configuration 클래스 - 스프링 설정 및 빈 등록을 위한 클래스
@Configuration 어노테이션이 붙은 클래스는 CGLib 를 활용해 싱글톤 빈 등록을 돕는다.

MyBean 객체를 생성하는 myBean()이 두 번 호출 되고 있다. 코드만 봐서는 객체가 두 번 생성되는 것이 맞다 => 싱글톤이 깨진 것 같다.
스프링은 해당 문제를 아래의 방법으로 해결한다.
프로그램 실행시(런타임) 대상 객체를 상속받아 프록시 객체를 생성해주는 프로그램
프록시 객체 - 원본 객체의 역할을 대신 수행해주는 도우미 객체.
스프링은 CGLib 라이브러리를 활용해 @Configuration 클래스를 상속받은 객체를 만든다.
원본 객체 대신 CGLib 가 생성한 객체의 메서드가 실행된다. 해당 객체가 싱글톤 방식의 객체 생성을 돕는다.
@Configuration 어노테이션의 유무로 CGLib 사용 여부가 결정된다. 해당 어노테이션이 없으면 싱글톤이 유지되지 않는다.
@Configuration 클래스는 프록시 객체를 통해 싱글톤 객체 생성을 한다.