본문 바로가기
기록해보기

UserController와 스프링 컨테이너

by titlejjk 2023. 6. 5.

이번에는 한 함수에서 세가지역할을 하는 것을 Controller Service Repository로 역할에 맞게 나누어봤는데 UserController에는 의아한 점이 있었는데 이 두가지를 정리하자면

첫번째로

static이 아닌 코드를 사용하려면 인스턴스화가 필요

인스턴스화를 하려면 생성자를 호출하게 되는데 (public UserController) 생성자는 만들었지만 인스턴스화를 한적은 없었다.

 

두번째로 

생성자를 호출하는 과정에서 UserController는 JdbcTemplate를 필요로 하고있다.

UserController는 JdbcTemplate에 의존하고 있는데

이 의존이라는 것이 UserController는 JdbcTemplate이 없으면 동작하지 않는 다는 의미이다.

 

하지만 우리는 JdbcController란 Class를 설정해준 적이 없다. 그러면 어떻게 UserController는 어떻게 JdbcTemplate을 가져올 수 있을까?

요놈!

@RestController라는 이 녀석 덕분이다. UserController클래스를 API의 진입지점으로 만들 뿐만 아니라 UserController 클래스를 스프링 빈으로 등록시키는 작업도 해준 것이다.

 

스프링 빈이란 무엇일까?

 

서버가 시작되면, 스프링 서버 내부에 거대한 컨테이너를 만들게 되는데,

생각하는 이것 맞다

그 컨테이너 안에는 여러 Class가 들어가게 된다.

서버가 시작될 때 스프링 컨테이너 안에 UserController가 들어가진다. 이때 Class만 들어가는 것이아니라 다양한 정보도 함께 들어가게 되고 인스턴스화도 이루어진다.

이러한 과정으로 첫번째 의문은 풀렸다.

 

이때 스프링 컨테이너 안으로 들어간 UserController를 스프링 빈 이라 한다.

두번째 의문점인 JdbcTemplate은 어디있을까?

사실 이 JdbcTemplate도 진작에 스프링 빈으로 등록이되어있다. 그래서 JdbcTemplate도 스프링컨테이너 안에있고 UserControllereh 스프링컨테이너에 안에 있기에 UserController를 인스턴스화할 때 JdbcTemplate도 같이 넣어주게 되는 것이다.

 

처음부터 정리해보자!

  1. 거대한 비어있는 스프링 컨테이너가 생성이 된다.
  2. 이 비어있는 스프링 컨테이너 안에 기본적으로 많은 스프링 빈들이 등록이 된다.
  3. 내가 설정해준 스프링빈이 등록이 된다.(예를들어 UserController)
  4. 이때 필요한 의존성이 자동으로 설정이 된다.(UserController에서 JdbcTemplate를 사용하는 것처럼)

그렇다면 왜 UserRepository는 JdbcTemplate을 가져오지 못할까?

JdbcTemplate을 가져오려면 UserRepositrory가 스프링 빈이여야 하는데 UserRepository는 스프링 빈이 아니기 때문이다. 바꿔말하면 UserRepository를 스프링 빈으로 등록하면 가져올 수 있다.

 

UserRepository를 스프링 빈으로 등록해보자. 방법은 간단하다.

UserRepository에 @Repository어노테이션을 걸어주면된다. 그 다음에 UserService도 스프링 빈으로 등록해보겠다

생각보다 쉬운데??..

이렇게 하면 어떤것이 달라질까?

 

먼저 UserRepository의 경우 JdbcTemplate를 바로 가져올수 있고, UserService는 UserRepository를 만들때 jdbcTemplate을 가져올 필요가 없어지게 된다.(두 개다 스프링 빈이 되었기 때문에)

 

그 다음 UserService 기존에 있던 JdbcTemplate이 필요한 것이 아니라 UserRepository가 필요하게 되고,

 

비슷하게 UserController역시 JdbcTemplate가 필요한 것이 아닌 UserService가 필요하게 된다.

 

 

정리해보자면

JdbcTemplate이 필요한 곳은 UserRepository에만 넣어줌으로 인해서 UserController와 UserService 에서 JdbcTemplate을 없애주고 Repository -> Service -> Controller 이런 순으로 받아서 사용할 수 있으며 이게 가능한 이유는 UserRepository를 스프링 빈으로 등록해 주어서 가능해 진 것이다.(UserService Class도 포함)

다 같은 스프링 빈이기에 JdbcTemplate을 바로 가져올 수 있수 있어 필요없기 때문에 각 클래스에서 지워주는 것이 가능하다.

 

Layered architecture를 생각해보면 더 이해하기 쉬울 것 같다.

 

그런데 말입니다..왜?!

스프링 컨테이너를 왜 사용하는 것일까? 그냥 new연산자를 쓰면 안될까? 라는 의문점이 생긴다.

이 부분은 다음에 알아보겠다! 간만에 배그판한 하러가야겠당 엫힣

댓글