예시 1) @Component 어노테이션을 기반으로 한 것

public class Client {
    public static void main(String[] args) throws IOException {
        BeanFactory beanFactory = new AnnotationConfigApplicationContext(ObjectFactory.class);
        PaymentService paymentService = beanFactory.getBean(PaymentService.class);
				PaymentService paymentService2 = beanFactory.getBean(PaymentService.class);
				
				System.out.println(paymentService); // bakuspring.spring6.service.PaymentService@120f102b
				System.out.println(paymentService2); // bakuspring.spring6.service.PaymentService@120f102b
				System.out.println(paymentService == paymentService2); // true
								
        Payment payment = paymentService.prepare(100L, "USD", BigDecimal.valueOf(50.7));
        System.out.println(payment);
    }
}

예시 2) @Bean을 기반으로 한 것

@Configuration
public class ObjectFactory {
    @Bean
    public PaymentService paymentService() {
        return new PaymentService(exRateProvider());
    }

    @Bean
    public ExRateProvider exRateProvider() {
        return new WebApiExRateProvider();
    }
}

public class Client {
    public static void main(String[] args) throws IOException {
        BeanFactory beanFactory = new AnnotationConfigApplicationContext(ObjectFactory.class);
       
        ObjectFactory objectFactory = beanFactory.getBean(ObjectFactory.class);
        PaymentService paymentService = objectFactory.paymentService();
        PaymentService paymentService2 = objectFactory.paymentService();

        System.out.println(paymentService); // bakuspring.spring6.service.PaymentService@3c947bc5
        System.out.println(paymentService2); // bakuspring.spring6.service.PaymentService@3c947bc5
        System.out.println(paymentService == paymentService2); // true
								
        Payment payment = paymentService.prepare(100L, "USD", BigDecimal.valueOf(50.7));
        System.out.println(payment);
    }
}

예시 3) OrderService, PaymentService 2개에 모두 ExRateProvider를 주입하도록 해봄

@Configuration
public class ObjectFactory {
    @Bean
    public PaymentService paymentService() {
        return new PaymentService(exRateProvider());
    }

    @Bean
    public OrderService orderService() {
        return new OrderService(exRateProvider());
    }

    @Bean
    public ExRateProvider exRateProvider() {
        return new WebApiExRateProvider();
    }
}

public class OrderService {
    final private ExRateProvider exRateProvider;

    public OrderService(ExRateProvider exRateProvider) {
        this.exRateProvider = exRateProvider;
    }
}

public class Client {
    public static void main(String[] args) throws IOException {
        BeanFactory beanFactory = new AnnotationConfigApplicationContext(ObjectFactory.class);
        PaymentService paymentService = beanFactory.getBean(PaymentService.class);
        OrderService orderService = beanFactory.getBean(OrderService.class);

        System.out.println(paymentService.exRateProvider == orderService.exRateProvider); // true
        
        Payment payment = paymentService.prepare(100L, "USD", BigDecimal.valueOf(50.7));
        System.out.println(payment);
    }
}

⇒ 모든 예시에서 서로 같은 객체라는 결과가 나옴. 즉, 싱글톤으로 관리됨을 확인할 수 있음