【JavaEE学习贴3】分析spring webmvc启动流程——servlet注册

Servlet

  • 是用java编写的服务端应用程序
  • 主要用于交互式的浏览和修改数据,生成web内容
  • 过程为:客户端发送请求到服务器 -> 服务器将请求信息发送至Servlet
    –>Servlet生成相应内容并将其传给服务器->服务器将响应返回给客户端。
    pdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NoYWRvd25vdw==,size_16,color_FFFFFF,t_70)

生命周期:

Servlet的生命周期可以分为四个阶段,即装载类及创建实例阶段、初始化阶段、服务阶段和实例销毁阶段。

1、初始化阶段 调用init()方法

2、响应客户请求阶段。调用service()方法,由service()方法根据提交的方式选择执行doGet()或者doPost()方法

3、终止阶段。调用destroy()方法

注册

Servlet元素用于注册一个Servlet,它包含两个主要的子元素:name和class,分别用于设置Servlet的注册名称和Servlet完整的类名。

一个servlet-mapping元素用于映射一个已经注册的Servlet的一个对外访问路径,包含有两个子元素:servlet-name和url-pattern,分别用于指定Servlet的注册名称(这个得与servlet的名称对应)和Servlet的对外访问路径。

<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>

使用servlet的话需要每个请求都去在web.xml中配置一个servlet节点,而Spring webmvc中的DispatcherServlet他会拦截所有的请求,进一步去查找有没有合适的处理器,一个前端控制器就可以。

javax.servlet.ServletContainerInitializer

这是servlet容器初始化的一个核心接口。

public interface ServletContainerInitializer {
    
    
    void onStartup(Set<Class<?>> var1, ServletContext var2) throws ServletException;
}

servlet容器会调用ServletContainerInitializer的onStartup方法,这也是spring mvc注册DispatcherServlet的入口。

@HandlesTypes({
    
    WebApplicationInitializer.class})
public class SpringServletContainerInitializer implements ServletContainerInitializer {
    
    
    public SpringServletContainerInitializer() {
    
    
    }

    public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {
    
    
        List<WebApplicationInitializer> initializers = new LinkedList();
        Iterator var4;
        if (webAppInitializerClasses != null) {
    
    
            var4 = webAppInitializerClasses.iterator();

            while(var4.hasNext()) {
    
    
                Class<?> waiClass = (Class)var4.next();
                if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
    
    
                    try {
    
    
                        initializers.add((WebApplicationInitializer)ReflectionUtils.accessibleConstructor(waiClass, new Class[0]).newInstance());
                    } catch (Throwable var7) {
    
    
                        throw new ServletException("Failed to instantiate WebApplicationInitializer class", var7);
                    }
                }
            }
        }

        if (initializers.isEmpty()) {
    
    
            servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
        } else {
    
    
            servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
            AnnotationAwareOrderComparator.sort(initializers);
            var4 = initializers.iterator();

            while(var4.hasNext()) {
    
    
                WebApplicationInitializer initializer = (WebApplicationInitializer)var4.next();
                initializer.onStartup(servletContext);
            }

        }
    }
}

WebApplicationInitializer的一个实现类AbstractContextLoaderInitializer

扫描二维码关注公众号,回复: 12629080 查看本文章
public abstract class AbstractContextLoaderInitializer implements WebApplicationInitializer {
    
    
    protected final Log logger = LogFactory.getLog(this.getClass());

    public AbstractContextLoaderInitializer() {
    
    
    }

    public void onStartup(ServletContext servletContext) throws ServletException {
    
    
        this.registerContextLoaderListener(servletContext);
    }

    protected void registerContextLoaderListener(ServletContext servletContext) {
    
    
        WebApplicationContext rootAppContext = this.createRootApplicationContext();
        if (rootAppContext != null) {
    
    
            ContextLoaderListener listener = new ContextLoaderListener(rootAppContext);
            listener.setContextInitializers(this.getRootApplicationContextInitializers());
            servletContext.addListener(listener);
        } else {
    
    
            this.logger.debug("No ContextLoaderListener registered, as createRootApplicationContext() did not return an application context");
        }

    }

    @Nullable
    protected abstract WebApplicationContext createRootApplicationContext();

    @Nullable
    protected ApplicationContextInitializer<?>[] getRootApplicationContextInitializers() {
    
    
        return null;
    }
}

到这里DispatcherServlet已经是注册到Servlet容器了。

猜你喜欢

转载自blog.csdn.net/Shadownow/article/details/105533282