일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- js XML 읽기
- js canvas
- response property
- dispatcherservlet 오류
- MySQL update delete
- Git
- scroll 맨 밑
- SWEA 1954 java
- SWEA 1228 python
- 탭 활용해 내용바꾸기
- web recorder
- tabs switch
- MySQL
- GitHub
- sw8931
- java
- Canvas
- scanner bufferedreader
- js session
- javascript
- scroll 맨 밑 이동
- CSS
- jQuery EventListener
- 페이지 내 탭
- SWEA 6190 python
- ReactMediaRecorder
- SWEA 11315 python
- request property
- $.ajax 사용
- js 객체생성
Archives
- Today
- Total
Daily Pogle
[Spring] 싱글톤패턴과 스프링 본문
스프링은 디자인 패턴으로 싱글톤 패턴을 사용하고 있다. 왜 싱글톤 패턴을 채택했을까?
스프링이 나온이유와 활용하고 있는 분야에 대해서 생각하면 이해하기 쉽다.
- 스프링은 기업용 온라인 서비스 기술을 지원하기 위해 나왔다.
- 대부분 웹 애플리케이션 개발을 위해 발전했다.
- 웹 애플레케이션은 많은 사용자들의 동시 요청이 들어온다.
이전 싱글톤 패턴을 적용하지 않은 순수 자바를 이용한 DI Containter를 살펴보자
class Web {
AppConfig appConfig = new AppConfig();
// user 1 : mebmerService 사용
MemberService memberService1 = appConfig.memberService();
// user 2 : mebmerService 사용
MemberService memberService2 = appConfig.memberService();
// user 3 : mebmerService 사용
MemberService memberService3 = appConfig.memberService();
// user1 은 정보조회, user2 은 정보수정, user 3 은 정보조회 등을 동시에 요청할 경우
void request() {
memberService1.getMember();
memberService2.updateMember();
memberService3.getMember();
}
// ...
}
- 이용자인 user 가 동시에 같은 service 에서 각 기능을 호출한다고 가정하면, n 명의 사용자가 memberService 에 있는 기능을 동시 요청했을 때, 최소 n개의 memberService 인스턴스가 생생되야한다.
- 이용자 트래픽이 초당 100이 나오면 초당 100개 객체가 생성되고 소멸되므로 메모리 낭비가 심하다.
- 메모리 낭비를 해결하기 위해서 하나의 memberService 객체를 생성하여 공유하도록 설계하는 싱글톤 패턴 을 사용하였다.
스프링의 싱글톤 컨테이너
스프링은 기존 싱글톤 패턴에서 나타나는 문제점들을 해결하여 사용할 수 있도록 설계하였다.
- 스프링 컨테이너는 싱글턴 패턴을 적용하지 않아도, 객체 인스턴스를 싱글톤으로 관리한다.
- 싱글톤 패턴을 위한 지저분한 코드가 들어가지 않아도 된다.
- DIP, OCP, 테스트, private 생성자로 부터 자유롭게 싱글톤을 사용할 수 있다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// 스프링 컨테이너 설정정보 클래스 예시
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
//...
}
class Web {
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
// 조회: 호출할 때 마다 같은 객체를 반환 - 서로 달라보여도 같은 인스턴스 재사용
MemberService memberService1 = ac.getBean("memberService", MemberService.class);
MemberService memberService2 = ac.getBean("memberService", MemberService.class);
MemberService memberService3 = ac.getBean("memberService", MemberService.class);
// user1 은 정보조회, user2 은 정보수정, user 3 은 정보조회 등을 동시에 요청할 경우
void request() {
memberService1.getMember();
memberService2.updateMember();
memberService3.getMember();
}
}
스프링 싱글톤 컨테이너 주의점
- 싱글톤 방식의 프로그래밍은 객체 인스턴스 하나만을 공유하여 사용하기 때문에, 싱글톤 객체는 유지(Stateful)하게 설계해서는 안된다.
- 항상 무상태(stateless)로 설계해야한다.
무상태로 설계하기 위해서는 다음과 사항을 지켜야한다.
- 특정 클라이언트에 의존적인 필드가 있으면 안된다.
- 특정 클라이언트에 의해 객체내 필드값이 변경되는 코드가 있어서는 안된다.
- 가급적 읽기만 가능해야한다, 변경이 불가능하게 끔해야한다.
- 객체의 필드 대신에 Java 에서 공유되지 않는 지역변수, 파라미터, 쓰레드로컬 등을 사용해야한다.
** 스프링 빈(객체)의 필드에 공유값을 설정하면 시스템에 큰 장애가 발생할 수 있다.
@Configuration
@Configuration 은 스프링 컨테이너가 해당 애노테이션을 사용한 클래스를 설정 클래스로 지정한다고 하였다. 하지만 @Configuration 는 더 중요한 역할을 맡고있다.
@Configuration 은 스프링 빈이 싱글톤을 유지할 수 있도록 스프링 빈에 등록된 클래스의 바이트 코드를 조작해준다.
CGLIB라는 바이트코드 조작 라이브러리를 사용해서 스프링 빈에 등록할 클래스를 전달받아 해당 클래스를 상속받은 임의의 다른 클래스를 만들고, 그 다른 클래스를 스프링 빈으로 등록해준다.
이때 임의로 상속받은 클래스를 실제 스프링 빈으로 등록하여, 싱글톤을 보장할 수 있도록 해준다.
만약 설정 클래스(AppConfig.class)에서 @Configuration 을 없애고 @Bean 만 사용할 경우, @Bean 으로 등록된 스프링 빈은 서로 다른 인스턴스를 가지고 있는 것을 확인 할 수 있다.
'백엔드 기술 > Spring' 카테고리의 다른 글
[Spring] BeanFactory, ApplicationContext, BeanDefinition (0) | 2023.11.07 |
---|---|
[Spring] spring 이란 (1) | 2023.11.04 |
[Spring] 주요 annotation 정리 (0) | 2023.03.06 |
[Spring] 파일 업로드/다운로드 기능 구현 (0) | 2023.02.28 |