spring web

源码

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer { /**
* Delegate the {@code ServletContext} to any {@link WebApplicationInitializer}
* implementations present on the application classpath.
* <p>Because this class declares @{@code HandlesTypes(WebApplicationInitializer.class)},
* Servlet 3.0+ containers will automatically scan the classpath for implementations
* of Spring's {@code WebApplicationInitializer} interface and provide the set of all
* such types to the {@code webAppInitializerClasses} parameter of this method.
* <p>If no {@code WebApplicationInitializer} implementations are found on the classpath,
* this method is effectively a no-op. An INFO-level log message will be issued notifying
* the user that the {@code ServletContainerInitializer} has indeed been invoked but that
* no {@code WebApplicationInitializer} implementations were found.
* <p>Assuming that one or more {@code WebApplicationInitializer} types are detected,
* they will be instantiated (and <em>sorted</em> if the @{@link
* org.springframework.core.annotation.Order @Order} annotation is present or
* the {@link org.springframework.core.Ordered Ordered} interface has been
* implemented). Then the {@link WebApplicationInitializer#onStartup(ServletContext)}
* method will be invoked on each instance, delegating the {@code ServletContext} such
* that each instance may register and configure servlets such as Spring's
* {@code DispatcherServlet}, listeners such as Spring's {@code ContextLoaderListener},
* or any other Servlet API componentry such as filters.
* @param webAppInitializerClasses all implementations of
* {@link WebApplicationInitializer} found on the application classpath
* @param servletContext the servlet context to be initialized
* @see WebApplicationInitializer#onStartup(ServletContext)
* @see AnnotationAwareOrderComparator
*/
@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...
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 有4个实现类 

1. AbstractContextLoaderInitializer

public abstract class AbstractContextLoaderInitializer implements WebApplicationInitializer {

    /** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass()); @Override
public void onStartup(ServletContext servletContext) throws ServletException {
registerContextLoaderListener(servletContext); //注册 监听器
} /**
* Register a {@link ContextLoaderListener} against the given servlet context. The
* {@code ContextLoaderListener} is initialized with the application context returned
* from the {@link #createRootApplicationContext()} template method.
* @param servletContext the servlet context to register the listener against
*/
protected void registerContextLoaderListener(ServletContext servletContext) {
WebApplicationContext rootAppContext = createRootApplicationContext(); //创建web根容器
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");
}
} /**
* Create the "<strong>root</strong>" application context to be provided to the
* {@code ContextLoaderListener}.
* <p>The returned context is delegated to
* {@link ContextLoaderListener#ContextLoaderListener(WebApplicationContext)} and will
* be established as the parent context for any {@code DispatcherServlet} application
* contexts. As such, it typically contains middle-tier services, data sources, etc.
* @return the root application context, or {@code null} if a root context is not
* desired
* @see org.springframework.web.servlet.support.AbstractDispatcherServletInitializer
*/
@Nullable
protected abstract WebApplicationContext createRootApplicationContext(); /**
* Specify application context initializers to be applied to the root application
* context that the {@code ContextLoaderListener} is being created with.
* @since 4.2
* @see #createRootApplicationContext()
* @see ContextLoaderListener#setContextInitializers
*/
@Nullable
protected ApplicationContextInitializer<?>[] getRootApplicationContextInitializers() {
return null;
} }

2 .  AbstractDispatcherServletInitializer

public abstract class AbstractDispatcherServletInitializer extends AbstractContextLoaderInitializer {
public static final String DEFAULT_SERVLET_NAME = "dispatcher"; public AbstractDispatcherServletInitializer() {
} public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
this.registerDispatcherServlet(servletContext);
} protected void registerDispatcherServlet(ServletContext servletContext) {
String servletName = this.getServletName();
Assert.hasLength(servletName, "getServletName() must not return null or empty");
WebApplicationContext servletAppContext = this.createServletApplicationContext();
Assert.notNull(servletAppContext, "createServletApplicationContext() must not return null");
FrameworkServlet dispatcherServlet = this.createDispatcherServlet(servletAppContext);
Assert.notNull(dispatcherServlet, "createDispatcherServlet(WebApplicationContext) must not return null");
dispatcherServlet.setContextInitializers(this.getServletApplicationContextInitializers());
Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet); //添加servlet
if (registration == null) {
throw new IllegalStateException("Failed to register servlet with name '" + servletName + "'. Check if there is another servlet registered under the same name.");
} else {
registration.setLoadOnStartup(1);
registration.addMapping(this.getServletMappings()); //添加mapping
registration.setAsyncSupported(this.isAsyncSupported());
Filter[] filters = this.getServletFilters();
if (!ObjectUtils.isEmpty(filters)) {
Filter[] var7 = filters;
int var8 = filters.length; for(int var9 = 0; var9 < var8; ++var9) {
Filter filter = var7[var9];
this.registerServletFilter(servletContext, filter);
}
} this.customizeRegistration(registration);
}
} protected String getServletName() {
return "dispatcher";
} protected abstract WebApplicationContext createServletApplicationContext(); protected FrameworkServlet createDispatcherServlet(WebApplicationContext servletAppContext) {
return new DispatcherServlet(servletAppContext);
} @Nullable
protected ApplicationContextInitializer<?>[] getServletApplicationContextInitializers() {
return null;
} protected abstract String[] getServletMappings(); @Nullable
protected Filter[] getServletFilters() {
return null;
} protected javax.servlet.FilterRegistration.Dynamic registerServletFilter(ServletContext servletContext, Filter filter) {
String filterName = Conventions.getVariableName(filter);
javax.servlet.FilterRegistration.Dynamic registration = servletContext.addFilter(filterName, filter);
if (registration == null) {
for(int counter = 0; registration == null; ++counter) {
if (counter == 100) {
throw new IllegalStateException("Failed to register filter with name '" + filterName + "'. Check if there is another filter registered under the same name.");
} registration = servletContext.addFilter(filterName + "#" + counter, filter); //添加filter
}
} registration.setAsyncSupported(this.isAsyncSupported());
registration.addMappingForServletNames(this.getDispatcherTypes(), false, new String[]{this.getServletName()});
return registration;
} private EnumSet<DispatcherType> getDispatcherTypes() {
return this.isAsyncSupported() ? EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ASYNC) : EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE);
} protected boolean isAsyncSupported() {
return true;
} protected void customizeRegistration(Dynamic registration) {
}
}

3   AbstractAnnotationConfigDispatcherServletInitializer

public abstract class AbstractAnnotationConfigDispatcherServletInitializer extends AbstractDispatcherServletInitializer {
public AbstractAnnotationConfigDispatcherServletInitializer() {
} @Nullable
protected WebApplicationContext createRootApplicationContext() {
Class<?>[] configClasses = this.getRootConfigClasses();
if (!ObjectUtils.isEmpty(configClasses)) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); //类似spring 中配置文件
context.register(configClasses);
return context;
} else {
return null;
}
} protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
Class<?>[] configClasses = this.getServletConfigClasses();
if (!ObjectUtils.isEmpty(configClasses)) {
context.register(configClasses);
} return context;
} @Nullable
protected abstract Class<?>[] getRootConfigClasses(); @Nullable
protected abstract Class<?>[] getServletConfigClasses();
}
public abstract class AbstractContextLoaderInitializer implements WebApplicationInitializer {

   /** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass()); @Override
public void onStartup(ServletContext servletContext) throws ServletException {
registerContextLoaderListener(servletContext);
} /**
* Register a {@link ContextLoaderListener} against the given servlet context. The
* {@code ContextLoaderListener} is initialized with the application context returned
* from the {@link #createRootApplicationContext()} template method.
* @param servletContext the servlet context to register the listener against
*/
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");
}
} /**
* Create the "<strong>root</strong>" application context to be provided to the
* {@code ContextLoaderListener}.
* <p>The returned context is delegated to
* {@link ContextLoaderListener#ContextLoaderListener(WebApplicationContext)} and will
* be established as the parent context for any {@code DispatcherServlet} application
* contexts. As such, it typically contains middle-tier services, data sources, etc.
* @return the root application context, or {@code null} if a root context is not
* desired
* @see org.springframework.web.servlet.support.AbstractDispatcherServletInitializer
*/
@Nullable
protected abstract WebApplicationContext createRootApplicationContext(); /**
* Specify application context initializers to be applied to the root application
* context that the {@code ContextLoaderListener} is being created with.
* @since 4.2
* @see #createRootApplicationContext()
* @see ContextLoaderListener#setContextInitializers
*/
@Nullable
protected ApplicationContextInitializer<?>[] getRootApplicationContextInitializers() {
return null;
} }

Spring MVC 源码 分析的更多相关文章

  1. 精尽Spring MVC源码分析 - 寻找遗失的 web.xml

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  2. 精尽Spring MVC源码分析 - 调式环境搭建

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  3. 精尽Spring MVC源码分析 - 文章导读

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  4. 精尽Spring MVC源码分析 - WebApplicationContext 容器的初始化

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  5. 精尽Spring MVC源码分析 - 一个请求的旅行过程

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  6. 精尽Spring MVC源码分析 - MultipartResolver 组件

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  7. 精尽Spring MVC源码分析 - HandlerMapping 组件(一)之 AbstractHandlerMapping

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  8. 精尽Spring MVC源码分析 - HandlerMapping 组件(二)之 HandlerInterceptor 拦截器

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  9. 精尽Spring MVC源码分析 - HandlerMapping 组件(三)之 AbstractHandlerMethodMapping

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  10. 精尽Spring MVC源码分析 - HandlerMapping 组件(四)之 AbstractUrlHandlerMapping

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

随机推荐

  1. vector引用参数

    #include<iostream> #include<vector> using namespace std; //定义一个计算数字的函数,返回计算后的vector numb ...

  2. php类知识 self $this都只能在当前类中使用

    $this是当前对象的指针,self是当前类的指针 $this只能用在成员方法中,不能存在于静态方法 self 静态方法和成员方法中都能使用 self可以访问类常量,静态属性,静态方法,成员方法--- ...

  3. 题解 【HEOI2016】tree树

    题面 解析 其实这题可以考虑离线做法,用并查集解决. 因为仔细想,添加标记并不方便, 但如果用并查集记录下祖先, 再一一删除,就会方便很多. 先把每次操作记录下来, 同时记录下每个点被标记的次数(因为 ...

  4. Spark配置详解

    Spark提供三个位置用来配置系统: Spark属性:控制大部分的应用程序参数,可以用SparkConf对象或者Java系统属性设置 环境变量:可以通过每个节点的 conf/spark-env.sh脚 ...

  5. 【Winform-自定义控件】自定义控件学习+一个笑脸控件例子

    1.CompositeControls组合控件:在原有控件的基础上根据需要进行组合 2.ExtendedControls 扩展控件:继承自原有控件,添加一些新的属性和方法,绘制一些新元素 当每个But ...

  6. 网络编程-UDP echo server

    1. UDP简介 UDP 和TCP 的区别包括 1. 面向字节流和面向报文 2. TCP必须要建立连接后才能进行数据交换,但是UDP则并没有连接的建立和释放过程.面向字节流说明,tcp报文段(segm ...

  7. Java基础__Integer类型中的自动装箱

    Integer类型的自动装箱:就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱. ...

  8. pyton3的数字操作你都会用吗?

    '''数字数据类型用于存储数值.数据类型是不允许改变的,这就意味着如果改变数字数据类型的值,将重新分配空间. 1.del(用于删除一些数字对象的引用) 2.整形(int)通常被称为是整形或者整数,是正 ...

  9. IDEA的小技巧:1.Java代码不被识别2.目录下创建的文件夹所显示样式不是文件夹,而是"包"图标样式的问题

    在Idea上面一个正常的代码结构是这个样子的,但是有的时候,比如说当我们直接在一个文件夹中随便的创建的时候就会出现一些问题,比如说想让某个地方为代码目录,某个地方为资源目录的时候,直接的创建目录是不成 ...

  10. TCP层accept系统调用的实现分析

    inet_csk_accept函数实现了tcp协议accept操作,其主要完成的功能是,从已经完成三次握手的队列中取控制块,如果没有已经完成的连接,则需要根据阻塞标记来来区分对待,若非阻塞则直接返回, ...