Spring

싱글톤 Singleton

김디니 2023. 6. 19. 20:59

싱글톤 객체란?

1개의 빈 객체를 생성하는 것이다.

 

예시 코드를 통해 싱글톤 객체를 알아보자.

package ...;

import ...annotation...;

public class Main {
	public static void main(String[] args) {
    	AnnotationConfigApplicationContext ctx =
           new AnnotationConfigApplicationContext(AppContext.class);
        
        // 객체 할당
        Greeter g1 = ctx.getBean("greeter", Greeter.class);
        Greeter g2 = ctx.getBean("greeter", Greeter.class);
        
        System.out.println("(g1 == g2) = " + (g1 == g2));
        ctx.close();

    }
}

 

주석처리된 코드 아래 "greeter"인 빈 객체를 구해서 g1g2 변수에 할당하는 코드를 작성하였다.

g1과 g2가 같은 객체라면 "true"를 반환하고 그렇지 않다면 "false"를 반환한다.

 

 

결론은 "true"를 반환한다.

 

 

❓왜 g1과 g2은 같은 객체일까?

분명 다른 변수에 할당하였으면 g1과 g2은 다른 객체이지 않을까? 

 

Greeter g1 = new Greeter();
Greeter g2 = new Greeter();

 

그동안 위 코드와 같이 JAVA의 new 키워드를 통해 객체를 생성했을 때 g1과 g2는 분명 다른 객체를 가지고 있을 것이다.

 

 

        // 객체 할당
        Greeter g1 = ctx.getBean("greeter", Greeter.class);
        Greeter g2 = ctx.getBean("greeter", Greeter.class);

 

하지만 스프링은 다르다.

스프링은 한 개의 빈 객체만을 생성한다. 이 때 빈 객체는 '싱글톤 범위를 갖는다' 라고 말할 수 있다. 

 

 

싱글톤은 단일 객체를 의미한다. 

스프링은 기본적으로 한 개의 @Bean 어노테이션에 대해 한 개의 빈 객체를 생성한다. 

 

 

 

한 개의 빈 객체를 생성한다는 것은

스프링이 자동적으로 하나의 객체만을 생성하는 것은 이해하였지만, 이것이 가지는 의미는 무엇일까.

 

 

 

 


 

싱글톤 패턴 Singleton pattern

 

어플리케이션이 시작될 때 최초의 한 번만 메모리를 할당하고(static) 해당 메모리에 인스턴스를 만들어 사용하는 패턴이다. 

 

즉, 하나의 인스턴스만 생성하여 사용하는 것이다.

똑같은 인스턴스를 만들지 않고 기존에 만들어 놓은 인스턴스를 재사용하는 것이다.

 

생성자가 여러 번 호출되어도 이미 생성된 객체를 반환하는 것이다.

 

public class ChatServiceImpl implements ChatService{
    private static ChatService instance = new ChatServiceImpl();
    ...
}

 

public class ChatController {
    private static ChatService chatService = ChatServiceImpl.getInstance();
    ...
}

 

위 코드들은 실제 프로젝트에서 사용한 코드이다. 

이처럼 생성자를 private으로 선언하여 다른 곳에서 생성되지 못하도록 하고 getInstance() 메소드를 통해 받아오도록 한다.

 

 

 

❓왜 싱글톤 패턴을 사용하는 것일까?

메모리 낭비를 방지할 수 있기 때문이다!

 

객체를 생성할 때마다 메모리 영역을 할당 받아야 한다. 

객체를 여기저기서 생성을 한다면 실상 잘 사용하지 않는 객체들도 많기 때문에 메모리 낭비를 하기 쉽다.

이를 방지하기 위해 전역으로 생성된 인스턴스를 다른 클래스의 인스턴스들이 사용하여 데이터를 공유할 수 있는 것이다.

 

 

 

주로 언제 사용할까?

  • DB: 커넥션풀, 스레드풀, 캐시, 로그 기록 등
  • 안드로이드 앱
커넥션풀
- DB와 미리 connection(연결)을 해놓은 객체들을 클라이언트 요청이 오면 connection을 빌려주고, 처리가 끝나면 다시 connection을 반납받아 pool에 저장하는 방식.

스레드풀
- 커넥션풀과 같이 미리 스레드를 pool에 저장해놓는 방식.
스레드: 프로그램 및 프로세스의 실행되는 흐름의 단위

 

 

 

단점

싱글톤 인스턴스가 많은 데이터들을 공유하게 되면서 다른 클래스들 간의 결합도가 높아지게 된다.

이는 개방-폐쇄 원칙이 위배된다.

 

 

'Spring' 카테고리의 다른 글

@Autowired Annotation  (0) 2023.07.04
스프링 DI  (0) 2023.06.20
[Spring] DI, IoC  (0) 2023.05.09