Learning and understanding of DispatcherServlet in Spring mvc

Process response

        The above figure shows the process of the response of the spring architecture when the customer request comes. You can see from the figure that the center of the request distribution is the DispatcherServlet class. The task of the DispatcherServlet is to send the request to the Spring MVC controller. A controller is a Spring component that handles requests. In a typical application there may be multiple controllers and the DispatcherServlet needs to know which controller the request should be sent to. So the DispatcherServlet will query one or more handler mappings to determine where the next stop for the request is. The processor mapping will make decisions based on the URL information carried by the request.

Understanding DispatcherServlet and ContextLoadListener

       DispatcherServlet requires a WebApplicationContext that inherits from ApplicationContext as a parameter to configure itself. WebApplicationContext is the associate of ServletContext and Servlet. For many applications, a WebApplicationContext is sufficient and can fully function. It is also possible when we have multiple DispatcherServlet and want to share a common bean in this application, so that we can define a root ApplicationContext contains all common beans and

      The root WebApplicationContext (root WebApplicationContext) actually already contains the beans that usually contain basics, such as data repostitories and business services that need to be shared by multiple servlet instances. These beans can be inherited and can be overridden (overridden) in a specific servlet, or in a child WebApplicationContext that contains a given servlet locally. The child WebApplicationContext is the Servlet WebApplicaitonContext as shown below.

      Explanation in the referenced article below

Spring's ApplicationContext provides the capability of loading multiple (hierarchical) contexts, allowing each to be focused on one particular layer, such as the web layer of an application or middle-tier services.

One of the canonical examples of using hierarchical ApplicationContext is when we have multiple DispatcherServlets in a web application and we're gonna share some of the common beans such as datasources between them. This way, we can define a root ApplicationContext that contain all the common beans and multiple WebApplicationContexts that inherit the common beans from the root context.

In the Web MVC framework, each DispatcherServlet has its own WebApplicationContext, which inherits all the beans already defined in the root WebApplicationContext. These inherited beans can be overridden in the servlet-specific scope, and you can define new scope-specific beans local to a given Servlet instance

      mvc-context-hierarchy

        FaolF

      If there is only one DispatcherServlet in the project, then we can move all the beans originally in DispatcherServlet to the parent class Root WebApplicationContext.

      Below is a configuration that implements a WebApplicationContext successor.

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] { RootConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { App1Config.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/app1/*" };
    }
}

        If the application context is not required to be inherited (the relationship between WebApplicationContext and child WebApplicationContext), then all configurations can be returned through getRootConfigClasses ( ) and getServletConfigClasses ( ) to return null. 

        In a Servlet 3.0 environment, the container will look in the classpath for a class that implements the javax.servlet.ServletContainerInitializer interface, and if it can find it, it will use it to configure the servlet container. Spring provides an implementation of this interface, named SpringServletContainerInitializer, which in turn looks for classes that implement WebApplicationInitializer and delegates configuration tasks to them. Spring 3.2 introduced a convenient base implementation of WebApplicationInitializer, AbstractAnnotationConfigDispatcherServletInitializer. Because our SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer (which also implements WebApplicationInitializer), when deployed to a Servlet 3.0 container, the container will automatically discover it and use it to configure the servlet context. (In short, it inherits AbstractAnnotationConfigDispatcherServletInitializer, which will form a child WebApplicationContext)

        Our own implementation of MyWebAppInitializer has the same effect as the xml file below.

<web-app>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/root-context.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>app1</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/app1-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>app1</servlet-name>
        <url-pattern>/app1/*</url-pattern>
    </servlet-mapping>

</web-app>

         Similarly, if the application context is not required to be inherited (the relationship between WebApplicationContext and child WebApplicationContext), then all configurations can be returned through the "root context", and the parameter contextLocation in the Servlet returns null.

Example to understand DispatcherServlet

         If I use Spring MVC, Spring Security and Spring Data JPA to build my application, then I need to know three config files, WebConfig contains web-related configuration, such as ViewResolvers, Controllers, ArgumentResolver, the code is as follows:

@EnableWebMvc
@Configuration
@ComponentScan(basePackages = "com.so.web")
public class WebConfig extends WebMvcConfigurerAdapter {
    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");

        return viewResolver;
    }

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        final boolean DO_NOT_USE_SUFFIX_PATTERN_MATCHING = false;
        configurer.setUseSuffixPatternMatch(DO_NOT_USE_SUFFIX_PATTERN_MATCHING);
    }
}

       Here we define a ViewResolver, and we need a RepositoryConfig configuration data-related classes, such as DataSource and TransactionManager, and so on.

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.so.repository")
public class RepositoryConfig {
    @Bean
    public DataSource dataSource() { ... }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() { ... }

    @Bean
    public PlatformTransactionManager transactionManager() { ... }

}

         SecurityConfig contains security-related members.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    @Autowired
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { ... }

    @Override
    protected void configure(HttpSecurity http) throws Exception { ... }
}

         Suppose we only have one DispatcherServlet Below we have two configuration methods:

  1 public class ServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
  2     @Override
  3     protected Class<?>[] getRootConfigClasses() {
  4         return new Class<?>[] { RepositoryConfig.class, SecurityConfig.class };
  5     }
  6 
  7     @Override
  8     protected Class<?>[] getServletConfigClasses() {
  9         return new Class<?>[] { WebConfig.class };
 10     }
 11 
 12     @Override
 13     protected String[] getServletMappings() {
 14         return new String[] { "/" };
 15     }
 16 }

         or

  1 public class ServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
  2     @Override
  3     protected Class<?>[] getRootConfigClasses() {
  4         return new Class<?>[] { RepositoryConfig.class, SecurityConfig.class, WebConfig.class };
  5     }
  6 
  7     @Override
  8     protected Class<?>[] getServletConfigClasses() {
  9         return null;
 10     }
 11 
 12     @Override
 13     protected String[] getServletMappings() {
 14         return new String[] { "/" };
 15     }
 16 }

ContextLoaderListener

         Bootstrap monitors the startup and shutdown of Spring's root WebApplicationContext. In Spring 3.1, ContextLoaderListener supports initializing root WebApplicationContext through ContextLoaderListener(WebApplicationContext).

special bean

         DispatcherServlet delegates to some special beans to process requests and return corresponding responses, these

DispatcherServlet

reference reading

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325230583&siteId=291194637