본문 바로가기
Back-End/Spring

TIL 230626 : Bean과 Singleton

by 우인입니다 2023. 6. 26.

Bean

처음 강의를 들으며 완벽히 이해하지 못 하고 넘어갔던 Bean.

다시 들어보니 찜찜한 구석이 보이기 시작했다.

 

Sevice클래스에 Repository를 생성자 주입하고 있다.

근데 가만 보면 PostRepository는 선언만 되고 생성은 되지 않았는데, 생성자에 어떻게 주입이 되고 있을까?

선언 하고 생성자가 없다는 걸 눈치 못 챘어서 예전 강의 때 '어디서 객체가 오는 걸까요?' 라는 말이 크게 와닿지 않았었다.

 

이렇게 생성하지 않았는데도 객체로 사용할 수 있는 것이 Spring의 Bean기능이다.

 

왼쪽에 커피콩처럼 보이는 것이 Bean객체화 되어서 관리되고 있다는 뜻이다. 이말인 즉슨 어딘가에선 저 Bean을 사용할 수 있다는 것이고,

아까 생성자 안에 객체 생성없이 바로 주입되는 것을 다시 보면 Bean이 사용되고 있음을 알 수 있다.

 

Bean의 사용방법

1. 우선 빈을 등록해야한다. (자동등록, 수동등록)

자동등록

@Component가 붙어있는 클래스라면 자동으로 Bean으로 등록되어 Container에서 관리된다.

@Service의 경우엔 들어가 보면 내부에 @Component를 포함하고 있고, 이와 같은 경우도 자동으로 등록된다.

 

물론 스프링의 시작과 함께 자동으로 생성되어 별다른 생성없이 사용가능했던 객체들이 있었다.

이것들 또한 자동으로 등록되어 사용하고 있었던 Bean들.

Spring뷰에서 Bean탭을 통해 확인할 수 있다.

 

수동등록

 

종종 수동으로 등록해서 사용해야 할 경우도 있다고'는' 한다.

 

해당 클래스에 @Configuration 어노테이션과 해당 메소드에 @Bean 어노테이션을 달면 메소드의 리턴값을 Bean객체로서 활용할 수 있다고 한다.

@Configuration
public class Config{

    @Bean
    public FilterRegistrationBean firstFilterRegister() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(new FirstFilter());
        return registrationBean;
    }
}

 

+주입받고 있는 Bean을 해제하면?

postService를 주입받고 있는 PostController

@Service 어노테이션을 주석처리하게 되면 PostService Bean객체로 사용을 못 한다.

아까는 있던 콩 마크가 안 보이고 Bean이 없다고 알람이 뜬다.

 

 

Bean은 singleton?

우선 싱글톤 패턴은 애플리케이션이 시작 될 때 static을 통해 인스턴스를 메모리에 딱 하나 할당하고, 뒤의 호출 시 마다 해당 인스턴스를 반환해주는 디자인 패턴이다. 생성자를 private으로 설정하기 때문에 외부에서 생성자를 통해 인스턴스를 만들 수 없다.

그런 특징과 비슷하게 Bean을 사용하는 이유는 '자주 사용하는 객체를 singleton으로 만들어 놓고 어디서든 불러쓸 수 있도록 한다.'에 의미가 있다고 한다.

 

 

싱글톤인 이유?

스프링으로 설계된 서버환경의 클라이언트에서 요청이 올 때마다 각 로직을 담당하는 오브젝트를 새로 만들어서 사용한다면 부하가 걸려 서버가 감당하기 힘들 것이다. 그래서 한 개의 오브젝트만 만들어 사용하는 것이 싱글톤 패턴의 원리이다.

 

싱글톤의 한계

private 생성자를 갖고 있어 상속할 수 없다.

싱글톤은 테스트하기 힘들다.

서버환경에서는 싱글톤이 하나만 만들어지는 것을 보장하지 못한다.

싱글톤 사용은 전역 상태를 만들 수 있기 때문에 바람직하지 못하다.

 

싱글톤 레지스트리

이러한 한계로 스프링은 싱글톤 레지스트리라는 직접 싱글톤 형태의 오브젝트를 만들고 관리하는 기능을 제공한다.

IoC 방식의 컨테이너를 사용해 제어권을 컨테이너에게 넘겨 싱글톤 방식으로 만들어져 관리되게 할 수 있다. 싱글톤 레지스트리 덕분에 애플리케이션 클래스라도 public 생성자를 가질 수 있으며 테스트하기도 편리해진다. 

 

 

스프링 빈의 Scope

스프링 빈이 생성되고, 존재하며 적용되는 범위를 스코프라고 한다. 스프링 빈의 기본 스코프는 싱글톤이다. 하지만 경우에 따라 다른 스코프를 가질 수 있다. 빈을 요청할 때 마다 새로운 오브젝트를 만드는 프로토타입 스코프, HTTP 요청이 생길때마다 생성되는 Request 스코프, 웹의 세션 스코프와 유사한 Session 스코프 등이 있다.

 

 

 

'빈의 싱글톤 사용은 전역상태를 만들 수 있기에 바람직하지 못하다.'라고 하는데
그 깊은 이유를 아직은 모르겠다.
싱글톤이라는 개념도 좀 더 공부가 필요하다.
중요한 건 이런 이유들의 근본적인 질문에 끊임없이 도전해야할 것 같은데,
무한 구글링만으로는 많이 힘에 부치고, 답답하다.