DispatchserServlet는 Spring MVC에 정의된 유일한 Front Controller입니다.
즉, Spring MVC에서 모든 요청을 받아 적절한 Controller와 View에 전달하고 요청에 대한 처리 결과를 출력하는 역활을 수행합니다.

<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/dispatcher-servlet.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
위와 같이 설정 되어 있는 경우 /WEB-INF/dispatcher-servlet.xml 파일을 참조하여 DispatcherServlet이 생성되고, 모든 요청에 대하여 처리합니다.
(contextConfigLocation을 생략할 경우 기본적으로 웹어플리케이션의 /WEB-INF/[서블릿이름]-servlet.xml 파일에서 정보를 읽어옵니다.)
DispatcherServlet는 요청한 URL을 처리하기 위한 Controller와 View를 연결 시켜 주는 역활을 합니다.
dispatcher-servlet.xml는 Handller와 ViewResolver 등의 class를 bean으로 등록합니다.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" > <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper" ref="objectMapper"/> </bean> </mvc:message-converters> <mvc:argument-resolvers> <bean class="MyArgumentResolver" /> </mvc:argument-resolvers> </mvc:annotation-driven> <bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean" /> <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
Xml에 DispatcherServlet의 다양한 설정을 추가할 수 있습니다.
개발자마다 다르긴 하지만, xml에 많은 설정들을 일일히 입력하는 것은 복잡하고 어렵습니다.
이에 Spring Boot가 등장하면서 많은 부분들이 생략되거나 간략화되었습니다.
최근에는 거의 대부분의 설정을 Java Configuration에 설정 가능하며, web.xml에 어떠한 설정도 하지 않아도 됩니다.
상세한 설정 내용은 Spring Boot를 정리하며 Java Configuration 기준으로 정리하고자 합니다.
Spring MVC는 다른 많은 웹프레임워크와 마찬가지로 Front Controller Pattern와 Command Pattern을 사용합니다.
Servlet은 다음과 같은 web.xml 설정을 통해 요청과 Servlet이 1:1로 mapping 됩니다.

<servlet> <servlet-name>hello</servlet-name> <servlet-class>HelloServlet</servlet-class> </servlet> <servlet> <servlet-name>world</servlet-name> <servlet-class>WorldServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> > <servlet-mapping> <servlet-name>world</servlet-name> <url-pattern>/world</url-pattern> </servlet-mapping>
public class HelloServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExceptionb, IOException { System.out.println("Do GET http method - /hello"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletExceptionb, IOException { System.out.println("Do POST http method - /hello"); } } public class WorldServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExceptionb, IOException { System.out.println("Do GET http method - /world"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletExceptionb, IOException { System.out.println("Do POST http method - /world"); } }
이러한 구조는 요청이 많아 질 수록 그만큼 Servlet도 많아져 복잡해집니다.
이러한 단점을 해결하고자 Front Controller Pattern이 등장하였습니다.
Front Controller을 해석하면 “앞에 있는 컨트롤”인 것처럼 모든 요청을 하나의 Servlet에서 받아 내부적으로 각 요청을 처리하는 형태입니다.

<servlet> <servlet-name>frontController</servlet-name> <servlet-class>FrontController</servlet-class> </servlet> <servlet-mapping> <servlet-name>frontController</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
public class FrontController extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExceptionb, IOException { String url = request.getRequestURI().substring(request.contextPath.length()); if(url.equals("/hello.do")) { System.out.println("Do GET http method - /http"); } else if(url.equals("/world.do")) { System.out.println("Do GET http method - /world"); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletExceptionb, IOException { String url = request.getRequestURI().substring(request.contextPath.length()); if(url.equals("/hello.do")) { System.out.println("Do POST http method - /http"); } else if(url.equals("/world.do")) { System.out.println("Do POST http method - /world"); } } }
FrontController 패턴은 모든 처리를 하나의 서블릿에서 처리하기 때문에 요청이 많아 질 수록 서블릿의 덩치가 커지게 됩니다.
Command 패턴은 Interface를 구현한 클래스에 요청을 분산 시켜 관리하는 디자인 패턴입니다.

<servlet> <servlet-name>frontController</servlet-name> <servlet-class>FrontController</servlet-class> </servlet> <servlet-mapping> <servlet-name>frontController</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
public interface Controller extends HttpServlet { } public class HelloController extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExceptionb, IOException { System.out.println("Do GET http method - /hello"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletExceptionb, IOException { System.out.println("Do POST http method - /hello"); } } public class WorldController extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExceptionb, IOException { System.out.println("Do GET http method - /world"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletExceptionb, IOException { System.out.println("Do POST http method - /world"); } } public class FrontController extends HttpServlet { public HelloController helloController = new HelloController(); public WorldController worldController = new WorldContoroller(); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExceptionb, IOException { String url = request.getRequestURI().substring(request.contextPath.length()); if(url.equals("/hello.do")) { helloController(request, response); } else if(url.equals("/world.do")) { worldController(request, response); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletExceptionb, IOException { String url = request.getRequestURI().substring(request contextPath.length()); if(url.equals("/hello.do")) { helloController(request, response); } else if(url.equals("/world.do")) { worldController(request, response); } } }
이처럼 Spring MVC는 FrontControllerPattern과 CommandPattern을 적용하여 구현됩니다.
공식 이름인 “Spring Web MVC”(이하. Spring MVC)는 Spring Framework의 모듈 중 하나인 “spring-webmvc”에서 유래하였습니다. Spring MVC는 Servlet API를 기반으로 구축된 최초의 웹 프레임워크입니다.
Spring MVC에 대해 말할 때, 항상 언급되는 것이 Model1과 Mode2입니다.
Model1과 Model2는 Java web application의 설계에서 흔히 사용되는 소프트웨어 디자인 패턴입니다.
(물론, Java web applicaion에서만 적용되는 디자인 패턴은 아닙니다.)
표시되는 부분과 로직을 하나의 서블릿에 함께 구현하는 디자인 패턴

표시되는 부분과 로직을 구별하여 구현하는 디자인 패턴

간단하게 정리하면, Logic과 Content가 함께 있느냐 없느냐로 보면 될 것 같습니다.
예전에는 JSP에 Java Code와 Html이 모두 존재하는 Model1로 많이 구현하였습니다..
하지만 웹디자이너와 웹개발자를 구분하기 시작하면서 JSP는 Html과 JavaScript 코드 등 View 역활만 하고, 서비스 로직은 별도의 Servlet에 구현하는 추세입니다.
M(Model) V(View) C(Controller)로 구분지어 구현하는 디자인 패턴
MVC는 소프트웨어 공학에서 사용되는 소프트웨어 디자인 패턴 중 하나입니다.
MVC에서 Model은 데이터를 나타내며, View는 사용자에게 보여지는 부분을, Controller는 Model과 View 사이의 상호동작을 관리합니다.

MVC에 Model1를 적용한 모델입니다.
JSP에 Model, Controller, View 코드가 모두 혼재되어 있습니다.
간단한 웹페이지를 구현할 때 사용됩니다.

MVC에 Model를 적용한 모델입니다.
Model, Controller, View가 모두 완벽히 분리되어 있습니다.
Spring MVC는 Spring Framework를 이용하여 MVC 디자인 패턴으로 구현하는 것을 말합니다.
Spring Framework는 이러한 MVC 구조로 구현하기 위한 다양한 모듈들을 포함하고 있으며, 많은 웹프로젝트가 MVC2 패턴을 사용하고 있습니다.
개인 생각 :
MVC2 디자인 패턴에서의 View는 단순히 사용자에게 데이터를 표출하는 역활을 하므로, JSP가 아닌 Html + JavaScript(+ UI Framework)로 구현하는게 좀 더 MVC스럽지 않나 생각합니다.
Spring Framework 뿐만 아니라 WPF, NodeJS 등 다른 Framework에서도 MVC 패턴과 유사한 패턴들(MVP, MVVM 등)로 구현하는게 최근 개발 트렌드인 것 같습니다.
Springdms 20여개의 모듈로 구성되어 기능을 제공합니다. 이러한 모듈은 다음 다이어그램과 같이 그룹화되어져 있습니다.

Spring DI의 핵심인 factory pattern을 Bean의 형태로 제공합니다.
(Spring Bean은 자주 사용하는 객체를 singleton 생성하고, 어디서든 사용 할 수 있습니다)
Spring Framework의 기본 기능을 제공하는 핵심 모듈입니다.
Core 및 Beans 모듈의 견고한 기반에서 다양한 기능을 제공합니다.
- JNDI 레지스티리와 유사한 방식의 객체 접근 방법 제공
- 국제화, 이벤트 전파, 리소스 로드, 컨테이너 작성 등의 기능 지원
- EJB, JMX 와 같은 JavaEE 기능 지원
런타임 시 객체 그래프를 쿼리하고 조작 할 수 있는 Expression Language를 제공합니다.
@Value 어노테이션과 같이 쓰일 수 있으며, 이 어노테이션과 SpEL의 조합을 통해 쉽게 데이터를 바인딩 할 수 있습니다.
AOP(관점 지향 프로그래밍)을 지원하기 기능들을 제공합니다.
AOP 모듈과는 독립적인 모듈로 AspectJ AOP를 지원합니다.
특정 애플리케이션 서버에서 사용되는 클래스 지원 수단 및 클래스 로더를 구현하기 위한 기능을 제공합니다.
(spring-instrument-tomcat 모듈은 Tomcat용 클래스 지원 및 를래스 로더를 제공합니다.)
메시지 기반 app을 작성할 수 있는 기능을 제공합니다.
JDBC를 사용하기 위한 템플릿 지원합니다.
트랜잭션 처리를 위한 추상 레이어를 제공합니다.
JPA, Hibernate와 같은 ORM API를 위한 통합 계층을 제공합니다.
JAXB, Castor, JiBX 밑 XStream과 같은 객체 / XML 매핑 구현을 지원하는 추상화 계층을 제공합니다.
JMS(Java Messaging Service) 모듈과의 통합을 제공합니다.
트랙잭션을 관리 기능을 제공합니다.
웹어플리케이션 개발을 위한 기본적인 기능을 제공합니다.
- spring-web : 멀티 파트 파일 업로드 기능 및 서블릿 리스너 등을 포함
- spring-webmvc : Spring의 MVC 및 REST 웹 서비스 구현을 위한 모듈
웹소켓을 지원하기 위한 추상 레이어를 제공합니다.
Servlet을 처리하기 위한 통합 게층을 제공합니다.
Portlet를 처리하기 위한 통합 계층을 제공합니다.
Spring의 Test를 수행하기 위한 기능들 제공합니다.
- JUnit 또는 TestNG를 사용하여 스프링 컴포넌트의 유닛 및 통합 테스트를 지원합니다.
- Spring ApplicationContext의 일관된 로딩과 캐싱 기능을 제공합니다.
- 테스트를 위한 Mock(모의 객체)을 제공합니다.
The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform.[원문]
Spring Framework(이하 Spring)는 모든 종류의 배포 플랫폼에서 최신 Java 기반 엔터프라이즈 응용 프로그램을 위한 포괄적인 프로그래밍 구성 모델을 제공합니다. 즉, Spring은 Java 기반의 엔터프라이즈 응용 프로그램를 개발하기 위한 Framework라고 할 수 있습니다.
엔터프라이즈라고 하니 JavaEE가 떠오릅니다.
그럼 JavaEE와 Spring는 어떤 관계 일까요?
JaveEE(Java Platform, Enterprise Edition; JavaEE 또는 J2EE)는 자바를 이용한 서버측 개발을 위한 플랫폼이며 JavaSE에 JSP, EJB, Servlet, JNDI 같은 기능이 추가된 플랫폼입니다.
특히 웹 개발을 위해 JavaEE에 포함된 JSP나 Servlet는 인기있는 CGI로 자리 잡게 되면서, WebLogic이나 JBoss 같은 JavaEE와 호환되는 웹 어플리케이션 서버(Web Application Server; WAS) 제품들이 출시 되었습니다.
이렇게 JavaEE는 많은 개발자들에게 주목을 받으며 널리 쓰이게 되었지만, 시간이 지남에 따라 몇 가지 심각한 문제가 발생하게 됩니다.
(EJB 기능 중 표준화가 되어 있지 않는 기능이 있어 이와 호환되는 어플리케이션 서버 제품에 종속되어 버린다거나, 배포하기 위한 설정이 너무 복잡하다거나, EJB와 호환하기 위해서 고가의 WAS가 필요하다거나 등등)
Windows10의 명령프롬프트에서 Mount를 정상적으로 수행하였는데, 윈도우 탐색기에 마운트된 드라이브가 보이지 않는 현상이 발생하였습니다.


해당 현상은, 명령프롬프트를 관리자 권한으로 실행하였기 때문입니다.
리눅스에서의 습관처럼 mount를 관리자 권한으로 실행하기 위해 명령프롬프트를 관리자 권한으로 실행하였고,
관리자 권한의 명령프롬프트에서 mount를 실행 한 것입니다.
윈도우 탐색기는 일반 권한(?)으로 실행되었기 때문에, 관리자 권한으로 마운트한 네트워크 드라이브가 보이지 않은 것입니다.
Mount 일반 사용자도 사용 가능한 명령어이므로, 명령프롬프트를 관리자 권한이 아닌 일반 사용자로 실행하면 됩니다.