Servlet

56 阅读1分钟

Servlet

在这里插入图片描述

  • GenericServlet、HttpServlet是属于javax.servlet.http。
  • FrameworkServlet、DispatcherServlet、HttpServletBean属于org.springframework.web.servlet。
  • XXXAware 在Spring中表示对XXX可以感知。实现这些接口后Spring会回调执行,并且将XXX返回给使用方。例如可以通过实现ApplicationContextAware接口可以获取到ApplicationContext。

HttpServletBean

将web.xml配置的参数设置到相应的属性。

<init-param>
    <!-- 应用application中某个Servlet中的ServletConfig对象可以获取以下配置的参数-->
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:springMvc.xml</param-value>
</init-param>
public final void init() throws ServletException {
	// Set bean properties from init parameters.
	// 获取到 init-param 标签的配置属性
	PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
	if (!pvs.isEmpty()) {
		try {
			BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
			ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
			bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
			// 设计模式:模板模式
			initBeanWrapper(bw);
			bw.setPropertyValues(pvs, true);
		}
	}
	// Let subclasses do whatever initialization they like.
	initServletBean();
}

FrameworkServlet

主要是创建webApplicationContext。

protected final void initServletBean() throws ServletException {
	this.webApplicationContext = initWebApplicationContext();
	initFrameworkServlet();
}
protected WebApplicationContext initWebApplicationContext() {
	WebApplicationContext rootContext =
			WebApplicationContextUtils.getWebApplicationContext(getServletContext());
	WebApplicationContext wac = null;
	if (this.webApplicationContext != null) {
		// A context instance was injected at construction time -> use it
		wac = this.webApplicationContext;
		if (wac instanceof ConfigurableWebApplicationContext) {
			ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
			if (!cwac.isActive()) {
				if (cwac.getParent() == null) {
					cwac.setParent(rootContext);
				}
				configureAndRefreshWebApplicationContext(cwac);
			}
		}
	}
	if (wac == null) {
		wac = findWebApplicationContext();
	}
	if (wac == null) {
		wac = createWebApplicationContext(rootContext);
	}
	if (!this.refreshEventReceived) {
		synchronized (this.onRefreshMonitor) {
			// 此处就是初始化Spring MVC九大组件:DispatcherServlet#onRefresh#initStrategies
			onRefresh(wac);
		}
	}
...
	return wac;
}
  • 获取spring的根容器rootContext。
  • 设置webApplicationContext并根据情况调用onRefresh方法。
  • 将WebApplicationContext设置到ServletContext。
protected WebApplicationContext createWebApplicationContext(@Nullable ApplicationContext parent) {
	...
	// wac = XmlWebApplicationContext
	ConfigurableWebApplicationContext wac =
			(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);

	wac.setEnvironment(getEnvironment());
	wac.setParent(parent);
	// web.xml 中<param-name>contextConfigLocation</param-name>  <param-value>classpath:springMvc.xml</param-value>
	String configLocation = getContextConfigLocation();
	if (configLocation != null) {
		wac.setConfigLocation(configLocation);
	}
	configureAndRefreshWebApplicationContext(wac);
	return wac;
}
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {
	...
	wac.setServletContext(getServletContext());
	wac.setServletConfig(getServletConfig());
	wac.setNamespace(getNamespace());
	wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));
	ConfigurableEnvironment env = wac.getEnvironment();
	if (env instanceof ConfigurableWebEnvironment) {
		((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());
	}

	postProcessWebApplicationContext(wac);
	applyInitializers(wac);
	// 调用Spring的refresh方法。开始IOC & AOP等功能
	wac.refresh();
}

WebApplicationContext

由FrameworkServlet创建WebApplicationContext。 在这里插入图片描述