본문 바로가기
코딩log/Spring Framework

[Spring Framework]@Configuration과 Singleton

by 벨크 2023. 3. 19.
반응형

  지난 포스팅에서 싱글톤 패턴과 스프링에서 IoC로 제공해 주는 싱글톤 레지스트리에 대해서 공부해 보았습니다. 이번 포스팅에서는 그 확장으로 스프링이 싱글톤을 보장해 주는 방법에 대해서 조금 공부해 보겠습니다.


@Configuration과 싱글톤

@Configuraion과 Singleton

 

Java로 작성된 의존관계 주입코드에서의 싱글톤

 

  스프링은 IoC 기능 중 하나로 싱글톤 레지스트리를 제공합니다. 쉽게 말하면 싱글톤 기능을 제공하는 레지스트리입니다. 싱글톤이란 특정 객체의 인스턴스가 JVM 내에 하나만 존재하도록 하는 디자인 패턴입니다.

 

  Bean으로 등록한 객체의 싱글톤은 스프링의 싱글톤 레지스트리가 관리를 한다고 하지만, Bean을 관리하는 Java 코드에서 싱글톤은 어떻게 지켜지는 것일까요?

@Configuration
public Class AppConfig {

    @Bean
    public Fedal fedal() {
        return new Fedal();
    }
    
    @Bean
    public Accelator accelator(){
        return new Accelator(fedal());
    }
    
    @Bean
    public Breaker breaker(){
        return new Breaker(fedal());
    }
}

 

  Bean을 관리하는 Java Class를 간단하게 구현해 보았습니다. Fedal(페달)이라는 Bean이 생성될 때, new Fedal();이라고 인스턴스가 하나 생성됩니다. 또 Accelator(액셀레이터)라는 Bean이 생성될 때, new Accelator의 생성자로 fedal()이 호출되고 fedal 함수 내에서 new Fedal() 이 되면서 또 하나의 인스턴스가 생성됩니다. Breaker를 생성시킬 때도 마찬가지로 new Breaker의 생성자로 fedal()이 호출되면서, 또 한 번 new Fedal()이 실행되고, 인스턴스가 생성됩니다.

 

  위의 코드는 스프링에서 생성된 코드가 아닌 개발자가 직접 작성하는 코드이고, 개발자가 작성한 자바코드를 스프링 프레임워크에서 임의로 수정하지 않는 이상 Fedal이라는 객체의 인스턴스는 3개가 생성되어야 합니다.

 

  하지만 실제로 위의 Java코드에 System.out.print를 하여 객체가 생성되기 전에 출력로그를 찍어보면, 놀랍게도 fedal() 함수는 한 번 밖에 호출되지 않습니다. Fedal에 대한 싱글톤을 스프링 프레임워크에서 보장한다는 뜻입니다. 어떻게 이런 일이 가능할까요?

 

@Configuration과 CGLIB

 

  비밀은 바로 Configuration Annotation에 있습니다. 스프링 프레임워크가 빌드될 때, @Configuration이 붙은 Java파일을 일반 Java파일과 조금 다른 방식으로 빌드를 합니다.

 

  CGLIB라는 이름의 Byte code 조작 Library를 사용하여 @Configuration이 붙은 Class를 상속받은, 임의의 Class를 생성시킵니다.(보통 @Configuration이 붙은 Class 이름의 첫 글자를 소문자로 바꿔 생성시킵니다.) 그리고 그 임의의 Class를 Bean으로 등록합니다. 등록된 @Configuration Bean 내부의 객체들이 호출될 때, 스프링 Bean으로 등록되어 있는지 여부를 확인하고, Bean으로 등록이 되어있으면 해당 Bean을 return 하고, 아니면 새로 Bean으로 등록하게끔 처리됩니다.

 

  어려운 이야기 같지만 단순하게 설명하자면, "@Configuration이 붙은 Java 파일을 CGLIB라는 라이브러리로 빌드해 새로운 Class를 생성시키고 스프링 Bean으로 등록하여 내부 함수들의 싱글톤을 보장한다."라고 생각하시면 됩니다.

 

  실제로 @Configuration을 빼고 실행을 시키면, 위의 예제에서 fedal() 함수가 3번 호출되어, Fedal 인스턴스가 3개가 생성되는 걸 확인할 수 있습니다.


  오늘은 Configuration Annotation을 이용해, 스프링 프레임워크가 싱글톤을 보장하는 방법에 대해서 알아보았습니다. @Configuration이 빠진 상태에서 빌드된 Java코드는 내부의 의존관계가 있는 객체는 Spring Bean이 아니게 되면서, Spring이 관리하지 않게 됩니다.

 

  따라서 의존관계를 주입하거나 의존관계를 정의하는 Class들은 어지간하면 @Configuration을 붙여서 스프링 Bean으로 관리하게 하는 것이 안전합니다.

 

  핵심내용은 간단하지만, 내부적으로는 복잡해 보이는 내용이었네요. 읽어주셔서 감사합니다!

 

이전 글: 싱글톤 레지스트리와 스프링 프레임워크

 

[Spring Framework]싱글톤 레지스트리와 스프링 프레임워크

앞서 스프링 프레임워크의 IoC 기능 중 의존관계 주입(Dependency Injection)에 관한 내용을 살펴보았습니다. 의존관계 주입이 스프링 프레임워크의 IoC 기능 중 가장 핵심이 되는 기능인데요. 오늘은

belklog.tistory.com

 

반응형

댓글