1.springmvc中DispatcherServlet继承体系
2.概述
springmvc是基于servlet的规范,servlet初始化会调用init方法,一个请求进来会根据请求类型调用doGet,doPost,doPut,doDelete,doOptions,doTrace等方法。
首先spring的HttpServletBean继承HttpServlet,作用是将web.xml中的标签属性解析为bean的属性,
3.HttpServletBean整个代码用工具翻译后的
https://blog.csdn.net/qq_39482039/article/details/118943723
4.实现EnvironmentCapable, EnvironmentAware作用
实现了spring环境有关的接口,主要作用是将web.xml配置的属性保存在ConfigurableEnvironment
环境里
5.HttpServletBean中覆盖了servlet的init方法
/**
* 将配置参数映射到该servlet的bean属性上,以及
* 调用子类初始化。
*
* @throws ServletException 如果bean属性无效(或必需)
* 属性丢失),或者子类初始化失败。
*/
@Override
public final void init() throws ServletException {
// 初始化参数设置bean属性.
//获取web.xml的配置参数,封装PropertyValues里
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
if (!pvs.isEmpty()) {
try {
//操作自身也就是操作子类DispatcherServlet
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
//将服务器的信息保存在spring的环境里
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
//留给子类处理
initBeanWrapper(bw);
//将web.xml配置信息赋值给DispatcherServlet
bw.setPropertyValues(pvs, true);
} catch (BeansException ex) {
if (logger.isErrorEnabled()) {
logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
}
throw ex;
}
}
// 让子类做他们喜欢的任何初始化。
initServletBean();
}
首先看第一行new了一个ServletConfigPropertyValues,将web.xml配置参数保存在ServletConfigPropertyValues
/**
* 创建新的ServletConfigPropertyValues.
*
* @param config 我们将使用ServletConfig获取PropertyValues
* @param requiredProperties 我们需要的属性名称集,其中
* *我们不能接受默认值
* @throws ServletException 如果缺少任何必需的属性
*/
public ServletConfigPropertyValues(ServletConfig config, Set<String> requiredProperties)
throws ServletException {
//requiredProperties是final修饰,所以如果不为空new一个HashSet
Set<String> missingProps = (!CollectionUtils.isEmpty(requiredProperties) ?
new HashSet<>(requiredProperties) : null);
//根据Servlet规范用getInitParameterNames方法获取所有配置的名称
Enumeration<String> paramNames = config.getInitParameterNames();
while (paramNames.hasMoreElements()) {
String property = paramNames.nextElement();
Object value = config.getInitParameter(property);
//将配置的值和名称保存在MutablePropertyValues
addPropertyValue(new PropertyValue(property, value));
if (missingProps != null) {
//清空之前的配置
missingProps.remove(property);
}
}
// 如果仍然缺少属性,则失败。
if (!CollectionUtils.isEmpty(missingProps)) {
throw new ServletException(
"Initialization from ServletConfig for servlet '" + config.getServletName() +
"' failed; the following required properties were missing: " +
StringUtils.collectionToDelimitedString(missingProps, ", "));
}
}
init方法之后如果PropertyValues不为空的话,大概主要的意思就是用BeanWrapper来操作JavaBean,也就是当前类,由于还有子类,应该是操作DispatcherServlet类将servlet中web.xml配置赋值给DispatcherServlet的属性,具体在FrameworkServlet中有一个contextConfigLocation属性,在web.xml中配置这个contextConfigLocation会FrameworkServlet进行处理,启用spring容器时会加载配置的xml文件,解析成一个bean保存在spring容器
最后留了一个initServletBean抽象方法给子类使用