Tomcat 실행시 스프링 내부 동작과정에 대해 설명해볼게요
Tomcat 실행했을 때 일어나는 동작
톰캣 실행전에 web.xml에 으로 전역 파라미터를 설정해요. 파라미터 이름은 contextConfigLocation이고 어떤 객체들을 미리 만들어 놓을지가 작성된 설정파일의 경로를 적어놔요.
톰캣이 실행되면 클래스(리스너)의 이름을 같은 web.xml에 작성해요. 톰캣을 실행하면
<listener>
가 등록되어 있는 ContextLoaderListener 객체를 호출하는데 이 객체는 내부적으로 부모객체를 실행해요. 부모객체는 ContextLoaderListener이며, 이 객체에서 Root ApplicationContext를 생성하고 웹과 관련이 없는 객체를 저장해요.(ex: dao)Root ApplicationContext 컨테이너에 객체들을 생성하기 위해서 contextConfigLocation 값으로 설정된 xml을 읽어요.(여기에선 applicationContext.xml)
즉 Context Loader Listener 를 통해 applicationContext.xml를 읽고, Root Application Context 컨테이너에 웹과 관련이 없는 객체들이 생성.
<context:annotation-config/>
을 작성해주면 어노테이션으로 설정을 하겠다고 선언하는거에요. 그리고 아래에<context:component-scan>
를 작성해주면 돼요. 스캔 할 base-package를 정의하고 @Repository, @Service, @Component 어노테이션을 스캔하겠다고 선언해줘요.
해당 base-package 클래스 위에 @Repository를 입력해주면 Root Application Context , 즉 Bean factory에 해당 객체가 싱글톤 형태로 저장이 돼요.
즉 ApplicationContext.xml에 의존성 주입을 위한 객체들을 미리 정의해요. 어노테이션 방식으로 선언하겠다고 지정도 하고 범위도 지정해줘요. 그러면 톰캣 실행시에 ContextLoaderListener 가 ContextLoader를 실행하고 컨테이너에 의존성 해결을 위한 객체들을 생성하게 돼요.
요청시 동작과정
- web.xml에 작성된 코드
spring org.springframework.web.servlet.DispatcherServlet spring /
모든 요청이 왔을 때 DispatcherServlet의 init() 메소드를 실행하라 라는 의미. (/ : 모든 요청)
만약 한번 요청이 왔었다면 init() 메소드는 생략이 가능해요.
위에 코드에서 servlet-name 이 spring 으로 되어 있으므로 init() 메소드는 spring-servlet.xml 파일을 읽어요.
- 어노테이션을 이용해 패키지를 검색할 수 있게 설정해야해요.
<context:annotation-config />
<context:component-scan base-package="패키지경로" />
base-package에 속한 클래스의 선언부에 @Controller 어노테이션을 추가하면 스캐닝이 이루어지고 , Web Application Context 컨테이너에 해당 객체를 저장해요.
그럼 톰캣을 생성했을 때 생성한 컨테이너(Root Application Context)에 있는 DAO 객체를 불러와요. @Autowired 를 이용해서 미리 생성된 객체를 불러올 수 있어요(DI)
@RequestMapping 어노테이션에 대하여 Handler Mapping 을 수행해요. 어떤 URL 이 올 때 어떤 메서드를 실행하겠다는 매핑 테이블을 만드는 거에요. @RequestMapping에 URL을 작성, 메서드에 수행할 로직을 처리하고 뷰에 전달하는 거예요. DispatcherServlet의 init() 메서드는 어떤 URL이 왔을 때 어떤 메서드를 실행할 것인지 Mapping을 만들어놔요.
스캐닝 과정을 거쳐 Mapping 테이블이 등록되면 이후의 요청은 DispatcherServlet의 init() 메서드가 실행되지 않을거에요.
service() 메서드가 실행되어 DispatcherServlet은 HandlerMapping 에게 질의를 하고 어떤 URL 요청에 어떤 메서드를 수행해야 할 지 분기를 시켜요.
컨트롤러는 return에 작성된 경로명을 보고 응답할 view를 찾기 위해 ViewResolver에게 질의해서 View 객체를 반환 받고 전달할 데이터를 추가하여 클라이언트에게 응답해요. (뷰 페이지에 데이터를 전달할 때 Model 객체를 써요.)
이상으로 스프링 내부 동작방식을 마치겠습니다.