Spring으로 여러 서비스를 만들면서 Controller, Service, Repository등의 레이어드 아키텍쳐만을 생각하고 코딩을 진행했었다. 근데 문득 공부했었던 Web server와 WAS등의 개념과 같이 생각하려고 하니깐 Web Server가 controller인가? 그럼 템플릿은 정적컨텐츠가 아닌데? MVC구조에서 Web server는 어디있지? 라는 생각에 아직 개념이 확실하지 않다는 생각을 하게 되었고 이에 글을 쓰게 되었다.
웹 서버 아키텍쳐
웹 서버의 아키텍쳐가 다양할 수 있다는 생각을 가지고 공부를 진행하면 좀 더 유연하게 공부를 진행할 수 있다.
먼저 대략적인 웹 서버와 WAS에 대한 내용을 잡고 싶으면 아래 글을 참고해주면 너무 좋을거 같다. 구독과 좋아요 부탁드립니다.🤗
https://me-analyzingdata.tistory.com/entry/%EC%9B%B9-%EC%84%9C%EB%B2%84%EC%99%80-WAS
사실 이렇게만 보면 웹서버와 Was는 독립적인 서버로만 생각 된다.
하지만 이는 아키텍쳐를
Client - Web Server - WAS - DB
로 잡아서 해석하면 그렇게 된다.
하지만 웹서버의 아키텍쳐는 보다 다양하게 설계되어질 수 있다.
Client - Web Server - DB : 정적인 컨텐츠만 처리하는 서버
Client - WAS - DB : WAS내에 Web Server를 포함하는 구조
이번 글에서는 Client - WAS - DB를 기본으로 잡고 설명을 진행하겠다.
전체 구조
설명을 진행하려는 웹서버의 전체적인 구조는 아래와 같다.
1. Tomcat
톰캣은 아파치 소프트웨어 재단의 WAS로서 자바 서블릿을 실행시키고 JSP코드가 포함되어잇는 웹페이지를 만들어준다.
WAS는 동적인 데이터를 처리하는 서버이다. Was안에는 정적인 데이터를 처리하는 Web Server와 동적 Data를 처리하는 Servlet Container가 존재하게 아키텍쳐를 설계했기 때문에 Was안에 Web Server가 존재하게 된다. 사실 Web Server가 어디있든 하는 일은 같겠지만 다시 정리해보자.
2. Web Server
Web Server의 기능은 3가지로 정리할 수 있을 것 같다.
- client와의 통신 담당
소켓과 관련된 네트워크 처리를 해준다. 즉, client의 request를 받고 이에 대한 응답인 response를 보내는 역할을 한다는 것이다. - 정적 컨텐츠 처리
정적소스는 웹 서버가 처리한다. 사용자가 요청한 request에 있는 URI로 가서 파일을 가지고 이를 반환해주는 간단한 일이기 때문에 이런거까지 servelet에게 넘겨 로드를 증가시킬 필요가 없기 때문이다. - Data전달
동적 컨텐츠 처리를 위한 request를 Web Container에게 전달하는 역할도 수행한다.
3. Servlet
위의 그림의 Servlet Container를 이야기하기 전에 Servlet이 무엇인지, 이걸 왜 Container로 관리해야하는지 이야기하겠다.
Servlet은 웹페이지나 결과 값을 동적으로 생성해 주기 위한 역할을 하는 자바 프로그램을 뜻한다. 해당 Servlet을 위한 Interface는 아래와 같은 코드를 가진다.
public interface Servlet {
public void init(ServletConfig config) throws ServletException;
public ServletConfig getServletConfig();
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
public String getServletInfo();
public void destroy();
}
이렇게 보면 우리는 Servlet이 생명 주기를 가지는 것을 알 수 있다. init - service - destroy 이렇게 말이다.
그렇기 때문에 이러한 생명 주기를 관리해주는 Servlet Container가 필요한 것이다.
4. Dispatcher Servlet
위의 그림을 보면 Servlet Container내부에 Sevlet은 없고 Dispatcher Servlet이 존재하는 것을 볼 수 있다.
말했다싶이 이 글은 Spring에서 어떻게 웹 서비스를 수행하는지를 이야기 하는 글이다. Spring에서는 Dispatcher Servlet이라는 구현체를 가진다. 그렇기 때문에 우리가 Spring을 가지고 코딩을 하면서 Servelt을 구현한 기억이 없는 것이다.
그럼 Dispatcher Servlet의 특징은 뭐가 있을까? 소스코드는 여기서 확인하면 된다.
이 글에서는 필요한 부분만 발췌해서 설명을 진행하겠다.
public class DispatcherServlet extends FrameworkServlet {
...
@Nullable
private static Properties defaultStrategies;
private boolean detectAllHandlerMappings = true;
private boolean detectAllHandlerAdapters = true;
private boolean detectAllHandlerExceptionResolvers = true;
private boolean detectAllViewResolvers = true;
private boolean throwExceptionIfNoHandlerFound = false;
private boolean cleanupAfterInclude = true;
...
}
위의 코드를 완전히 이해할 수는 없지만 우리는 몇가지 특징을 발견할 수 있다.
- HandlerMappings
Spring으로 Controller를 구현하게 되면 Servlet 규약에 대해서 신경을 안 쓰는 것을 알 수 있다. 이는 HandlerMapping을 통해 DIspatcherServlet이 request에 맞는 Controller를 찾아주기 때문이다.
Q) 어떻게 DispatcherServlet은 Request와 Controller를 mapping을 진행할까?
https://me-analyzingdata.tistory.com/entry/Spring-MVC-DispatcherServlet%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-request%EB%9E%91-controller%EB%A5%BC-%EC%9D%B4%EC%96%B4%EC%A4%84%EA%B9%8C
다음글을 읽어보면 알 수 있을 것이다.
- HandlerAdapter
HandlerAdapter는 HandlerExecution, 즉 Handler랑 Intercepter들이 이어져있는 메소드랑 Controller랑 이어져있는 객체로 여기에 request를 넘기면 handler Adpter를 통해 Controller Bean 객체가 호출되어 결과가 도출이되고 이를 다시 HandlerExecution를 통해 DispatcherServlet으로 넘어간다.
5. Spring Container
Spring framework의 중요한 특징 중 하나는 IoC Container가 존재한다는 것이다.
IoC란 Inversion of Control의 약자로 제어의 역전을 뜻하는 말이다.
이러한 IoC Container로는 Spring framework에서 2개가 존재한다.
첫번째로는 BeanFactory로 Bean을 관리하는 기능을 가지고 있는 Container다. 즉, Bean의 생성, 관리, 소멸의 전반적인 부분을 담당한다.
두번째로는 Application Context이다. ApplicationContext가 상속받고 있는 것들을 보면서 해당 Context의 역할을 살펴보자
다음은 소스 코드에 담겨잇는 설명이다.
Central interface to provide configuration for an application. This is read-only while the application is running, but may be reloaded if the implementation supports this.
An ApplicationContext provides:
Bean factory methods for accessing application components. Inherited from ListableBeanFactory.
The ability to load file resources in a generic fashion. Inherited from the org.springframework.core.io.ResourceLoader interface.
The ability to publish events to registered listeners. Inherited from the ApplicationEventPublisher interface.
The ability to resolve messages, supporting internationalization. Inherited from the MessageSource interface.
Inheritance from a parent context. Definitions in a descendant context will always take priority. This means, for example, that a single parent context can be used by an entire web application, while each servlet has its own child context that is independent of that of any other servlet.
In addition to standard org.springframework.beans.factory.BeanFactory lifecycle capabilities, ApplicationContext implementations detect and invoke ApplicationContextAware beans as well as ResourceLoaderAware, ApplicationEventPublisherAware and MessageSourceAware beans.
See Also:
ConfigurableApplicationContext, org.springframework.beans.factory.BeanFactory, org.springframework.core.io.ResourceLoader
Author:
Rod Johnson, Juergen Hoeller
- ListableBeanFactory : BeanFactory의 메소드로 application component에 접근할 수 있는 메소드라고 한다. 해당 방법을 상속 받아 Application Context가 빈에 대해 접근할 수 잇는 것 같다.
- ResourceLoader : generic한 방법으로 file을 load할 수 있는 인터페이스이다.
- ApplicationEventPublisher : 등록된 listeners들에게 event를 publish할 수 있는 기능을 가지고 있다.
- MessageSource : 다국어 메세지를 풀 수 있는 기능을 가지고 있다는데 뭔 소린지 모르겠다.
부가적으로 해당 Context는 Parent Context로 부터 전달 받았다고 한다. 그 말은 두가지 의미를 가지고 있는데 첫번째로는 부모 Context에 바뀐 내용을 자식들이 받을 수 있다는 것과 두번째로는 자식이 만약 자신만의 Context를 가진다면 해당 Context가 우선시 된다는 것이다.
이렇게 보면 Application Context는 빈생성, 메세지 해독, event관리 등의 능력을 포함하고 여러 Context가 hierarchical하게 설정되어 관리되는 것을 알 수 있다.
Spring Container에는 이러한 Application Context가 2개 존재한다.
1. Servlet Web ApplicationContext
뭔가 말만 들어도 두개가 합쳐진 느낌이 난다. 사실 맞는 말 같다. 이는 Servlet Context와 WebApplication Context가 합쳐진 말 같다. 틀리면 댓글 남겨주시면 감사하겠습니다.
- ServletContext : 모든 Servlet이 공유하는 context로 Servlet Container와 servlet이 소통할 수 있는 메소드가 정의가 되어있는 인터페이스이다.
- WebApplicationContext : 일반적인 ApplicationContext에서 getServletContext라는 메소드가 추가된 인터페이스이다. 따라서 최상위 Context인 Applicatoin Context와 부모 자식 관계를 가지며 Servlet Context와 연관관계를 가지는 Context이다.
2. Root WebApplicationContext
최상위 Context로 모든 Servlet WebApplicationContext의 부모 Context이다. 기본적인 Servlet WebApplicationContext와의 차이점은 View자원이외에 모든 Context가 사용이 가능한 Infra, Log자원등을 구성할 때 사용된다는 것이다.
참조
https://unordinarydays.tistory.com/131
https://mangkyu.tistory.com/151
'개발 > Spring' 카테고리의 다른 글
[Spring] Spring과 Paging - [1] (0) | 2022.01.20 |
---|---|
[Spring] Spring Security의 이해 (0) | 2022.01.19 |
[Spring]@Transactional과 JUnit Test (2) | 2022.01.11 |
[Spring MVC] DispatcherServlet은 어떻게 request랑 controller를 이어줄까? (0) | 2022.01.06 |
[Spring JPA] ORM과 JPA (1) | 2022.01.05 |