美文网首页spring 相关
Spring注解--全注解方式写web服务(一):web容器启动

Spring注解--全注解方式写web服务(一):web容器启动

作者: aix91 | 来源:发表于2019-01-15 21:15 被阅读0次

1. 启动类

Web容器在启动时,会去扫描每个 jar 包 META-INF/services下的javax.servlet.ServletContainerInitializer文件。在spring-web的jar包中,可以看到类似的结构:


在该文件里引入了SpringServletContainerInitializer
@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
      ...
}

从@HandlesTypes可以看出,在web容器初始化的时候,会去自动扫描WebApplicationInitializer接口下的所有子类(AbstractContextLoaderInitializer,AbstractDispatcherServletInitializer,AbstractAnnotationConfigDispatcherServletInitializer)

  • AbstractContextLoaderInitializer 中引入了 ContextLoaderListener
protected void registerContextLoaderListener(ServletContext servletContext) {
        WebApplicationContext rootAppContext = createRootApplicationContext();
        if (rootAppContext != null) {
            ContextLoaderListener listener = new ContextLoaderListener(rootAppContext);
            listener.setContextInitializers(getRootApplicationContextInitializers());
            servletContext.addListener(listener);
        }
        else {
            logger.debug("No ContextLoaderListener registered, as " +
                    "createRootApplicationContext() did not return an application context");
        }
    }
  • AbstractDispatcherServletInitializer:创建WebApplicationContext(将实现方法开放给继承),并为webContext添加servlet和filter
protected void registerDispatcherServlet(ServletContext servletContext) {
        String servletName = getServletName();
        // 创建WebApplicationContext,由子类实现
        WebApplicationContext servletAppContext = createServletApplicationContext();
        //创建DispatcherServlet
        FrameworkServlet dispatcherServlet = createDispatcherServlet(servletAppContext);
        dispatcherServlet.setContextInitializers(getServletApplicationContextInitializers());

        ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet);

        registration.setLoadOnStartup(1);
        registration.addMapping(getServletMappings());
        registration.setAsyncSupported(isAsyncSupported());

        Filter[] filters = getServletFilters();
        if (!ObjectUtils.isEmpty(filters)) {
            for (Filter filter : filters) {
                registerServletFilter(servletContext, filter);
            }
        }
        customizeRegistration(registration);
    }
  • AbstractAnnotationConfigDispatcherServletInitializer 定义了servlet容器和根容器的创建方法,但是开放出配置类,让子类去实现,从而实现自定义config类。
  1. 创建根容器
@Override
    protected WebApplicationContext createRootApplicationContext() {
        Class<?>[] configClasses = getRootConfigClasses();
        if (!ObjectUtils.isEmpty(configClasses)) {
            AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext();
            rootAppContext.register(configClasses);
            return rootAppContext;
        }
        else {
            return null;
        }
    }
  1. 创建web容器
@Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext servletAppContext = new AnnotationConfigWebApplicationContext();
        Class<?>[] configClasses = getServletConfigClasses();
        if (!ObjectUtils.isEmpty(configClasses)) {
            servletAppContext.register(configClasses);
        }
        return servletAppContext;
    }

2. 实现

  • 实现AbstractAnnotationConfigDispatcherServletInitializer
public class MyWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    //获取根容器的配置类
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{com.test.tournesol.mvc.RootConfig.class};
    }

    //web 容器的配置类,MVC的配置类
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{com.test.tournesol.mvc.AppConfig.class};
    }

    //获取DispatcherServlet的映射信息
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}
  • 定义根容器配置类
@ComponentScan(value = "com.test.tournesol.mvc", excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})
})
public class RootConfig {
}
  • 定义web容器配置类
@ComponentScan(value = "com.test.tournesol.mvc", includeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})
}, useDefaultFilters = false)
@EnableWebMvc
public class AppConfig {
}
  • 定义与业务相关的Controller 类和 Service类

相关文章

网友评论

    本文标题:Spring注解--全注解方式写web服务(一):web容器启动

    本文链接:https://www.haomeiwen.com/subject/yebedqtx.html