Spring学习系列第一章------------初识SpringMVC源码

上一章,我们学习了servlet3.0的基础特性,在servlet3.0中,最突出的特性就是注解式和编程式动态添加和配置设置。所以我们在查看Springmvc源码的时候,也是从这个地方入手。
我们现在很多项目,都是采用的注解方式,而取消掉了以前的配置文件,web.xml和application.xml,这些实现的方式其实就是使用了编程式添加配置。现在让我们一起来看一看,如何配置Springmvc

Springmvc 原理

源码分析

//根据我们之前分析的servlet3.0, 发现SpringWeb中的SpringServletContainerInitializer实现了
//ServletContainerInitializer  这个也就是Springmvc的入口
//WebApplicationInitializer 为所有初始化的接口, 实现了接口中的 onStartup方法
@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {

 @Override
 public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
   throws ServletException {

  List<WebApplicationInitializer> initializers = new LinkedList<>();

  if (webAppInitializerClasses != null) {
   for (Class<?> waiClass : webAppInitializerClasses) {
    // Be defensive: Some servlet containers provide us with invalid classes,
    // no matter what @HandlesTypes says...
       //获取到所有的WebApplicationInitializer实现,如果不是接口,不是抽象类
       //并且是WebApplicationInitializer,则进行实例化放入 LinkedList initializers
    if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
      WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
     try {
      initializers.add((WebApplicationInitializer)
        ReflectionUtils.accessibleConstructor(waiClass).newInstance());
     }
     catch (Throwable ex) {
      throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
     }
    }
   }
  }

  if (initializers.isEmpty()) {
   servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
   return;
  }

  servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
  AnnotationAwareOrderComparator.sort(initializers);
  for (WebApplicationInitializer initializer : initializers) {
   initializer.onStartup(servletContext);
  }
 }
}

WebApplicationInitializer 实现类

diagram1

如何通过编程式使用Springmvc

​ 根据之前的过程,我们需要一个 WebApplicationInitializer实现类,而通过上图我们知道,AbstractAnnotationConfigDispatcherServletInitializer 是最下面的抽象类,所以我们可以从AbstractAnnotationConfigDispatcherServletInitializer这个类入口,适配器模式


public class MySpringMvc extends AbstractAnnotationConfigDispatcherServletInitializer{

  /**
   * Specify {@code @Configuration} and/or {@code @Component} classes for the
   * {@linkplain #createRootApplicationContext() root application context}.
   *
   * @return the configuration for the root application context, or {@code null} if creation and
   * registration of a root context is not desired
   */
  @Override
  protected Class<?>[] getRootConfigClasses() {
    return new Class[0];
  }

  /**
   * Specify {@code @Configuration} and/or {@code @Component} classes for the
   * {@linkplain #createServletApplicationContext() Servlet application context}.
   *
   * @return the configuration for the Servlet application context, or {@code null} if all
   * configuration is specified through root config classes.
   */
  @Override
  protected Class<?>[] getServletConfigClasses() {
    return new Class[0];
  }

  /**
   * Specify the servlet mapping(s) for the {@code DispatcherServlet} &mdash;
   * for example {@code "/"}, {@code "/app"}, etc.
   *
   * @see #registerDispatcherServlet(ServletContext)
   */
  @Override
  protected String[] getServletMappings() {
    return new String[0];
  }
}

以MySpringmvc 为基础 看看是如何调用的

这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/whw174660897/article/details/80903086