저번 글에서 (좀 오래되긴 했지만..ㅎ) app config를 사용해서 di사용 하는걸 해보았다.
하지만 아직 왜 스프링을 사용하는가에 대한 질문은 답을 하지 못했다.
이글에서 그에대한 것을 정리 해보려고 한다.
스프링 컨테이너
일단 저번 코드의 appconfig 역할을 대신 하는것이 많이 들어왔던 ApplicationContext(스프링 컨테이너) 이다.
스프링 빈의 개념을 한번 집고 넘어가면
스프링 컨테이너가 @Configuration을 붙여 정의된 설정 정보를 사용하여
@Bean이라 적힌 모든 메서드를 호출해 반한된 객체를 스프링 컨테이너에 등록한다.
이렇게 등록된 객체를 스프링 빈이라 한다.
스프링 컨테이너 생성 과정, 빈등록, 의존관계 설정등 많이 중요한 내용들이 있지만 이건 나중에 따로 정리하도록 하고
지금은 왜 스프링을 사용하는가에 집중 하겠다.
위에서 말했듯이 스프링컨테이너는 appconfig의 역할을 대신한다.
하지만 코드만 봤을경우 더 복잡해지고 어려워지는 느낌이 든다. 그럼에도 왜 스프링 컨테이너를 사용할까?
appconfig 사용시 문제점
AppConfig appConfig = new AppConfig();
TestService testService1 = appConfig.testService();
TestService testService2 = appConfig.testService();
System.out.println("memberService1 = " + memberService1);
System.out.println("memberService2 = " + memberService2);
appconfig문제점을 보여주는 예시 코드이다.
결론 부터 말하면 appconfig를 사용하면 요청이 들어올때 마다 testService가 새롭게 생성되어 효율적인 면에서 매우 안 좋다.
그런데 여기서 잘 이해가 안되었다.
그냥 테스트 코드에서 각각 생성 해주니 당여히 2개 다르게 생성되는거 아니야? 실제동작은?
아마 컨트롤러 없이 예시가 있다보니 내 머리에 있는 실제 동작이랑 연결시켜 내지 못해서 그런거 같다.
(기초 이해 없이 먼저 마구잡이로 개발하며 알게된 것들이 더 헷갈리게 하는거 같다)
- id로 user를 조회하는 요청이 있다하자.
- id값을 요청으로 받게 될 것 이다.
- service에 생성자 통해서 appconfig내용이 주입된다(UserRepository).
- 이때 userRepository 객체가 생성된다.
- 근데 동시에 다른 id 요청이 들어온다.
- 그럼 똑같은 방식으로 userRepository가 또 생성된다.
이런식이면 100개 요청이 들어오면 100개의 서로 다른 객체가 생성되며 메모리 낭비가 심해진다.
appconfig 문제점 해결법1
해결방안은 객체를 하나만 생성하고 그 객체를 공유하도록 설계하면된다.
이런한 방법을 싱클톤 패턴이라고 한다.
싱글톤 패턴으로 예시 service를 만들어 보겠다.
public class SingletonService {
private static final SingletonService instance = new SingletonService();
public static SingletonService getInstance(){
return instance;
}
private SingletonService(){}
public void logic(){
System.out.println("싱글톤 로직");
}
}
static 영역에 객체 instance를 미리하나 생성해서 올려둔 후 getInstance 메서드를 통해서 조회한다.
생성자를 private로 막아 외부에서 객체 생성을 막는다.
하지만 이 방법엔 많은 문제점이 있다.
- 구현 코드가 많이 들어간다
- 클라이언트가 구체 클래스에 의존한다 (getInstance()로 접근)
- private 생성자로 자식 클래스를 만들기 어렵다.
- 내부 속성을 변경하거나 초기화 하기 어렵다.
결론적으로 코드의 유연성이 떨어진다
그럼 어떻게 해야할까?
appconfig 문제점 해결법2
이제 스프링컨테이너가 등장한다.
스프링 컨테이너는 이 모든 문제를 해결해 준다.
스프링 컨테이너는 스프링빈을 싱클톤으로 관리하지만 위 싱글톤의 단점을 해결해준다.
스프링에서 싱클톤 방식에 대해선 다음글에 자세히 정리할겠다.
- 스프링 컨테이너는 싱글톤 패턴을 적용하지 않아도, 객체 인스턴스를 싱글톤으로 관리
- 싱글톤 레지스트리 : 싱글톤 객체를 생성하고 관리하는 기능
(물론 기본 빈 등록 방식이 싱글톤이고 다른 방식도 지원한다.)
결론
왜 스프링을 사용할까에 대한 궁금증에 대한 답이 나왔다.
헷갈렸던 이유는 di를 사용 하는이유 = 스프링 사용하는 이유라고 생각했던 거 같다.
스프링으로 프로젝트도 하나 했었는데 이런것도 모르고 했다는게 참... 열심히하자
'Spring' 카테고리의 다른 글
| [spring] 스프링 login (0) | 2024.02.21 |
|---|---|
| [스프링] 스프링빈이 없다면? (0) | 2023.12.04 |
| [프로젝트] dto, mapper 개념 (0) | 2023.10.27 |
| [스프링] Security (0) | 2023.08.05 |
| [스프링] 트랜잭션 (0) | 2023.08.04 |