SpringMVC로드 프로세스

 이 섹션에서는 SpringMVC는 경량 웹 프레임 워크의 요청 기반 MVC 디자인 패턴 자바 구현의 유형을 기반으로, SpringMVC에 대해 설명합니다. 이 장에서는 개념, 프로세스를 소개하고, 다음 소스를 설명합니다.

1. MVC

 보기 (보기) - - 방법 컨트롤러 (컨트롤러) 비즈니스 로직, 데이터 디스플레이 및 인터페이스 분리 MVC (모델 뷰 컨트롤러) 프레임 모드의 소프트웨어 설계, 그것은 모델 (모델)을 사용합니다. MVC 패턴은 MVC 세 가지 핵심 요소가되는 복합 프레임 패턴

  • 모델 (모델) 사용자 데이터, 상태 및 프로그램 로직의 조회 및 제어와 무관
  • 보기 (보기) : 프로그램의 웹 인터페이스와 유사 제시된 모델은 뷰는 동일한 데이터에 대한 표시 (보기)의 다양한 형태를 가질 수있다, 모델에서 데이터를 상태를 보여주고받을 필요가있을 것이다
  • 컨트롤러 (제어기) : 일반적으로 컨트롤러의 뷰를 갖는 상기 해석 모델에 사용자 입력 정보 및 코멘트를 취득해야

2. SpringMVC 과정

 나는 우리가 인터넷에서이 사진을 볼 생각 :

파일

이 도면은 HTTP를 SpringMVC 기본적인 처리를 요청하는 과정을 도시하고, 대응하는 프로세스이다 :

  • 사용자는 프론트 엔드의 DispatcherServlet 제어기에 요청을 전송한다.
  • DispatcherServlet은 모든 HandlerMapping 프로세서 호 매퍼에 대한 요청을 수신한다.
  • (이 생성되는 경우) 프로세서 맵퍼 (메모 찾을 구성 XML)에 따라 특정 처리를 찾은 개체 생성 프로세서 및 프로세서 인 인터셉터 함께 DispatcherServlet으로 되돌아갑니다.
  • DispatcherServlet을 호출 HandlerAdapter 프로세서 어댑터.
  • (또한 백 - 엔드라고도 컨트롤러) 특정 적응 통화 프로세서 통해 HandlerAdapter.
  • 컨트롤러는 완전한 반환의 ModelAndView을 수행 할 수 있습니다.
  • HandlerAdapter 컨트롤러의 ModelAndView 결과는 DispatcherServlet에에 백업 할 수 있습니다.
  • 의 DispatcherServlet의 ModelAndView는 ViewReslover 뷰 리졸버를 전달합니다.
  • ViewReslover 반환 특정보기 분석.
  • (모델 데이터가 채워진보기를 예정)보기를보기를 렌더링의 DispatcherServlet.
  • 사용자에게 DispatcherServlet에 응답.

 이 모두가 데모와 접촉합니다 :

web.xml에

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>
复制代码

applicationContext.xml에서 패키지와 태그 검색 액세스 지정

<context:component-scan base-package="xxx" />

<mvc:annotation-driven />复制代码

컨트롤러 추가

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String excute() {
        return "hello";
    }
}复制代码

다음으로 상기 한 바와 의미

  • 봄로드 개방의 ContextLoaderListener 루트 컨텍스트, 해당 구성 applicationContext.xml 파일
  • 열기의 DispatcherServlet 모니터 / * 부하 모두에 요구 WebContext, 해당 구성 파일 디스패처-servlet.xml 파일
  • 스캔 패키지 경로, 오픈 MVC 주석 지원 지정
  • @RestController 컨트롤러 객체를 이용하여 해당 컨트롤러 추가 라벨링 프로세스 요청 경로를 사용하여 라벨 @RequestMapping

3. SpringMVC로드 프로세스

 리스너와 서블릿 : SpringMVC 로딩은 주로 두 가지 기술적 인 점에 의존, 서블릿 컷에 따라 달라집니다.

3.1. ContextLoaderListener에 로딩

 우리는 web.xml에 리스너 서블릿 기술에 ContextLoaderListener에 의존에서 알 수있다. servlet2.3 첨가 수신기가 주로 모니터하는 세션 요청 상황 등을 위해 사용된다. 사용 리스너는 해당 인터페이스를 구현해야합니다. 리스너 때 트리거 이벤트, 바람둥이 자동으로 리스너의 적절한 방법을 호출합니다. 일반적으로 사용되는 모니터 인터페이스는 다음과 같습니다 :

  • HttpSessionListener : 세션 생성과 파괴를 듣고.
  • ServletRequestListener : 창조와 파괴의 수신 요청
  • ServletContextListener는 : 창조와 파괴의 문맥을 듣고.

여기 ServletContextListener의 주요 사용은 서블릿 초기화하기 전에 사용자 지정 작업을 수행하는 데 사용.

 다음과 같이 ContextLoaderListener에 정의 :

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
    public ContextLoaderListener() {
    }
    
    public ContextLoaderListener(WebApplicationContext context) {
        super(context);
    }
    
    @Override
    public void contextInitialized(ServletContextEvent event) {
        initWebApplicationContext(event.getServletContext());
    }
    
    @Override
    public void contextDestroyed(ServletContextEvent event) {
        closeWebApplicationContext(event.getServletContext());
        ContextCleanupListener.cleanupAttributes(event.getServletContext());
    }
}复制代码

이 클래스 ContextLoader를 상속하고, 초기화 contextInitialized 법 (ServletContext를 전달), contextDestroyed 방법에 의해 파괴 된 자원 회수에 의해 수행된다. ContextLoader를 초점 방법을 찾으십시오.

 ContextLoader를 초기화 동안, 먼저 코드 내부의 정적 블록을 수행 할 것이다 :

private static final Properties defaultStrategies;

static {
    try {
        ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);
        defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
    }
    catch (IOException ex) {
        throw new IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());
    }
}复制代码

이 단계는 속성 객체 defaultStrategies를 초기화하는 데 사용되는 기본 구성 파일의 역할을 할 것이다 클래스 경로 ContextLoader.properties에 구성 파일을로드합니다.

3.1.1. contextInitialized

 다음과 같이 주요 내용 contextInitialized 방법은 다음과 같다 :

파일

프로세스는 다음과 같습니다

(1) 현재의 콘텍스트가 초기화되었는지 여부를 판정한다.

 ServletContext 내 org.springframework.web.context.ROOT에 의해 결정되는 값에 키가 있는지 여부

  • 초기화의 WebApplicationContext는 다음과 같이 ContextLoader.properties에서의 WebApplicationContext의 구체적인 실현을 찾기 :
 org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext复制代码

XmlWebApplicationContext이 확인한 다음 클래스를 초기화

(2) 구성과 XmlWebApplicationContext이 새로 고침

 다음 XmlWebApplicationContext이 상속도이다 :

파일

더 명백한 수준 자체는 (세부 내용의 기간에 볼 수있다)를 RefreshableConfigApplicationContext이다. 그것의 부모 객체 자체는 또한 다음과 같은 몇 가지 기본 속성을 유지 ServletConfig를 ServletContext에 두 개의 관련 웹 컨텍스트를 보존

DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";复制代码

이 속성은 기본 경로 Spring 설정 파일입니다.

 그것은 주목해야한다 XmlWebApplicationContext이 재 작성 loadBeanDefinitions의 부모 클래스

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // Configure the bean definition reader with this context's
    // resource loading environment.
    beanDefinitionReader.setEnvironment(getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // Allow a subclass to provide custom initialization of the reader,
    // then proceed with actually loading the bean definitions.
    initBeanDefinitionReader(beanDefinitionReader);
    loadBeanDefinitions(beanDefinitionReader);
}

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
        for (String configLocation : configLocations) {
            reader.loadBeanDefinitions(configLocation);
        }
    }
}
    
@Override
protected String[] getDefaultConfigLocations() {//Tip:返回配置文件路径
    if (getNamespace() != null) {
        return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
    }
    else {
        return new String[] {DEFAULT_CONFIG_LOCATION};
    }
}复制代码

XmlBeanDefinitionReader는 콩을 해결하기 위해 정의 여기에 사용하고, 논리적 프로필로드의 getConfigLocations 지정 부모 클래스 configLocations이 비어 있지 않은 경우, 값이 반환되고, getDefaultConfigLocations의 그렇지 않으면 반환 값을. getDefaultConfigLocations 방법의 논리는 다음과 같습니다 네임 스페이스가있는 경우는 true, 그렇지 않은 경우는 /WEB-INF/applicationContext.xml을, 구성 파일로 /WEB_INF/namespace.xml을 반환합니다. 위의 데모에 해당하는 파일 구성 (동일한 기본 값으로) 돌아왔다.

 다음과 같이 XmlWebApplicationContext이 초기화 단계는 다음과 같습니다

  • ContextId 구성 설정을 읽어
  • 는 contextConfigLocation하지 기본 프로필이 DEFAULT 위에서 언급 한 경우, 구성 파일, 구성을 지정 읽기 는 config LOCATION
  • 로드 contextInitializerClasses는 지정된 클래스, 컨텍스트 새로 고침하기 전에 사용자 정의 처리를 수행하는 데 사용
  • XmlWebApplicationContext이의 새로 고침 메서드를 호출

(3) 플래그는 초기화 된

 결정 ServletContext 내 루트 컨텍스트의 현재 상태 및 설정된 값 org.springframework.web.context.ROOT, (1) 단계에서

3.1.2. contextDestroyed

 파괴 공정이 비교적 간단하고, 모든 org.springframework 제거 먼저 콘텍스트의 확대 방법의 WebApplicationContext 파괴를 호출하고 최후의 ServletContext의 속성 값 org.springframework.web.context.ROOT의 ServletContex 제거. 속성 값 시작.

3.2. DispatcherServlet을 로딩

 ContextLoaderListener에 비슷한으로, 서블릿 확장에 따라 DispatcherServlet을. 구조 다음의 DispatcherServlet :

파일

위 상기의 HttpServlet에서 DispatcherServlet으로 상속하고, 상기 HTTP 요청을 처리하기위한 방법을 doService 재기록 :

3.2.1. HttpServletBean

 HttpServlet을 상속 재산에 서블릿을 저장하는 구성 항목에 대한 ConfigurableEnvironment 증가했다. init 메소드를 재 기입함으로써, 구성 항목 서블릿 초기화 컨텍스트 변수에 추가되며, 그 과정에서 서브 클래스 개방 initBeanWrapper initServletBean.

3.2.2. FrameworkServlet

 웹 기반 프레임 워크 서블릿 서블릿 각 내부 XmlWebApplicationContext이 개체 및 네임 포맷 servletname와 - 서블릿에 대응하였습니다. 상기 위에 경우가 어디 구성 파일 경로의 표시 설정, 현재까지이다 /WEB-INF/namespace.xml 스프링 구성 파일로서 대응한다 사용될 스페이스 데모 /WEB-INF/dispatcher-servlet.xml . FrameworkServlet 재 intServletBean 부모 클래스, 초기화 XmlWebApplicationContext이 작동합니다. XmlWebApplicationContext이 서블릿으로 초기화에서, 시도가하는 ServletContext 컨텍스트의 루트 얻기 위해 현재의 부모 컨텍스트 컨텍스트 및 설정 (위에서 언급 루트 Ccontext의 ServletContext 플래그로 초기화 된에 배치됩니다), 다음 NVC 루트 Contextde에 따라 초기화 과정은 초기화합니다. 차이는 리프레시 개구 구멍을 포함하기 전에 확장 될 것이라는 것이다 :

  • 내부 서브 방법을 재기록함으로써 postProcessWebApplicationContext
  • 로드 및 실행 ApplicationContextInitializer 클래스 구성 globalInitializerClasses에 의해 외부

FrameworkServlet doXXX 또한 상위 클래스의 다양한 방법을 우선, 우리는 processService 방법에 http 프로세스 요청합니다. processService 결국 doService 방법에 위탁.

3.2.3. DispatchdrServlet

 주요 치료, SpringMVC HTTP 요청을 달성하기 위해 주로 두 가지를 완료하는 것입니다 :

3.1. onRefresh 재 작성 방법

 처리 전략, HandlerAdapter 처리 전략, HandlerException 처리 전략,보기 분석 전략을 모든 HandlerMapping, 문서 처리 전략 : 포함, 초기화의 숫자에 대한 기본 전략을 설정합니다. 프로세스의 HTTP 각 단계에서 SpringMVC은 필터와 유사한 메커니즘을 제공하는 프로세서 정책 복수 등록 할 각 단계는 정책이 현재 요청의 순서로 선택되고, 그 처리 할 수있다. 다음과 같이 기본 정책의 대부분은 스프링 MVC 모듈 / 웹 / 서블릿 / DispatcherServlet.properties 파일에 조직 / 스프링 프레임 워크 간주합니다 :

파일

여기 내 데모입니다 (SpringBoot)의 경우는 각 속성과 각 정책 등록 된 런타임의 DispatcherServlet

파일

RequestMappingHandlerAdapter의 주요 관심사 RequestMappingHandlerMapping에서 HandlerMapping에와 handlerAdapters. 이 두 가지가 DispatcherServlet.properties 파일에 지정된하지만 오픈에없는 자동 등록 후에는이 나중에 소개합니다.

3.1.1 RequestMappingHandlerMapping 초기화

 주로 다음과 같이 @RequestMapping 주석 처리기, 그 상속을 찾는 데 사용 RequestMappingHandlerMapping :

파일

  • AbstractHandlerMapping : 그 핸들러를 획득의 주요 성과를 제공하는 인터페이스를 구현하는 모든 HandlerMapping. 는 GetHander 실현 방법을 사용하면 특정 핸들러가 getHandlerInternal 서브 클래스에 위임하고 현재 요청 경로 인터셉터는 HandlerExecutionChain을 반환과 관련된과 함께 포장 된 찾을 것입니다. 모두가 빈 MappedInterceptor 인터페이스를 달성하기위한 인터셉터, 컨텍스트 초기화를 AbstractHandlerMapping 때 찾을 통과합니다.
  • AbstractHandlerMethodMapping 다음 AbstractHandlerMapping에 기초하여, 주로 핸들러 메소드를 조회 대응 제공 요청, 즉 getHandlerInternal 방법에 따라 구현. 이러한 상황은 초기에 모든 콩을 통과하며, 다음 콩, 현재 탐색 방법 (getMappingForMethod 의한 방법) (isHandler 방법에 의해), 각 방법은 lookUpPath를 대응하는 완전한 경로 콩 규정 함했다 . getHandlerInternal 구현도 lookUpPath HttpServletRequest의 요청에 대응하여 얻어지는에서 다음 캐시 메모리에서 해당 핸들러를 취득한다.
  • RequestMappingHandlerMapping : @RequestMapping 구현, isHandler 및 getMappingForMethod의 주요 성과.
    • isHandler는 : @Controller는 메모 나 주석 @RequestMapping을 표시할지 여부를 결정
    • getMappingForMethod는 : 주석의 RequestMappingInfo @RequestMapping 예를 돌려줍니다.
      3.1.2 RequestMappingHandlerAdapter 초기화

  다음과 같이 RequestMappingHandlerAdapter 주로 ,, 그 상속을 HandlerMethod의 이행을 완료합니다 :

파일

  • AbstractHandlerMethodAdapter : 전달할 필요의 구현을 지원할 수 있는지 여부를 결정하기위한 처리기 HandlerMethod 핸들러 인스턴스 대리인 핸들러 메소드 handleInternal 서브 클래스를 실행하는 데있다.
  • RequestMappingHandlerAdapter : 해상도 파라미터 리졸버 다양한 입력 기준으로서 반사 촉구 대응 실제 구현 방법 대상물 핸들러, 다양한 처리 작업의 결과에 대한 변환기 통화.

3.2. 다시 쓰기 방법 doService

 HTTP 요청의 처리는 다음과 같은 특정 흐름도, 즉, 초기의 HTTP 요청에 SpringMVC 한 처리는, 처리 이전에 유입 된 이물질은 여기서 반복되지 않는다.

파일

3.3. MVC : 주석 중심의

 따라와 자원 봐 / META-INF / spring.handlers 파일, 봄-webmvc 모듈이 구성이 말한다, 전에 말했듯이 :

http\://www.springframework.org/schema/mvc=org.springframework.web.servlet.config.MvcNamespaceHandler复制代码

다음과 같이 태그를 지원 :

파일

주석 중심의 수업 분석 : AnnotationDrivenBeanDefinitionParser는, 메인 클래스는 자동으로 다음과 같은 작업을한다 :

  • RequestMappingHandlerMapping과 BeanNameUrlHandlerMapping은이 모든 HandlerMapping을 달성 주입
  • 주입 된 RequestMappingHandlerAdapter, HttpRequestHandlerAdapter 및 SimpleControllerHandlerAdapter 세 HandlerAdapter 달성. 존재하는 경우 RequestMappingHandlerAdapter위한 어떠한 메시지 컨버터 태그 지정 배치 없다고 언급되는 메시지 처리부 후 상기 프로세서는 자동 클래스 경로 분사 포함하는 본 패키지 :
    • ByteArrayHttpMessageConverter
    • StringHttpMessageConverter
    • ResourceHttpMessageConverter
    • SourceHttpMessageConverter
    • AllEncompassingFormHttpMessageConverter
    • 이 com.rometools.rome.feed.WireFeed 경우 클래스 증가 AtomFeedHttpMessageConverter, RssChannelHttpMessageConverter
    • 이 com.fasterxml.jackson.dataformat.xml.XmlMapper 클래스 증가 MappingJackson2XmlHttpMessageConverter하는 경우
    • 이 javax.xml.bind.Binder 클래스 증가 Jaxb2RootElementHttpMessageConverter하는 경우
    • 이 com.fasterxml.jackson.databind.ObjectMapper 및 com.fasterxml.jackson.core.JsonGenerator, 증가 MappingJackson2HttpMessageConverter하는 경우
    • 이 com.google.gson.Gson 경우, GsonHttpMessageConverter 증가
  • @ExceptionHandler 메모를 구현하기위한 ExceptionHandlerExceptionResolver을 주조, @ResponseStatus 및 DefaultHandlerExceptionResolver을 구현하기위한 ResponseStatusExceptionResolver을 주입
  • 주입 통로 해상도 UrlPathHelper위한 AntPathMatcher

 상술 한 방법은 일반적으로, 세부 사항은 파람 @ 다양한 파라미터의 주입 및 분석, HttpServletRequest의로 설명되지 물론 SpringMVC 구현되는, 같은 위의 상세한 설명 캔에 따른 추천 JSON에 각종 처리 결과의 결과에 응답하여,의 다음에 깊이 실시하고 있습니다.

4. WebApplicationInitializer

 Servlet3.0 +는 타사 구성 요소가 웹 컨테이너에서 시작하는 기회를 제공하는 등 등록 된 서블릿 또는 filtes로 등 일부 초기화 작업을 할 ServletContainerInitializer 인터페이스를 제공합니다.

 각각의 프레임은 당신이 META-INF / 서비스 디렉토리는 해당 항아리 패키지 javax.servlet.ServletContainerInitializer라는 이름의 파일을 작성해야합니다 ServletContainerInitializer를 사용하려면, 파일의 내용은 특정의 ServletContainerInitializer 구현 클래스를 지정합니다. 모듈의 존재 배치 스프링 웹 것이다 :

파일

말한다 :

org.springframework.web.SpringServletContainerInitializer复制代码

주요 기능은 모든 클래스 경로 SpringServletContainerInitializer WebApplicationInitializer 구현 클래스 (비 인터페이스, 비 추상 클래스) @Order 따라 정렬 후 순차적 onStartup WebApplicationInitializer 실행 방법을 로딩하는 것이다.

 추상 클래스 모듈은 스프링 웹 AbstractContextLoaderInitializer web.xml을 구성 증가 RootContext없이 달성 될 수있다 제공한다 AbstractDispatcherServletInitializer 추상 클래스는 web.xml을 구성 DispatcherServlet을 증가시키지 않으면 서 달성 될 수있다. 무엇보다 중요한 것은 실현 SpringBoot을 달성하는 것입니다,이 때 다음 소개 SpringBoot 언급.

더 원본 콘텐츠 마이크로 채널 대중 번호를 검색하십시오 : 아 낙타를 (doubaotaizi)

추천

출처juejin.im/post/5e149bc4e51d45413846f876