在上一篇博客springMVC源码分析--容器初始化(二)DispatcherServlet中,我们队SpringMVC整体生命周期有一个简单的说明,并没有进行详细的源码分析,接下来我们会根据博客中提供的springMVC的生命周期图来详细的对SpringMVC的相关源码进行分析。

在上一篇博客中我们了解到,SpringMVC初始化配置是在父类HttpServletBean的init方法中,其实HttServletBean是一个比较简单的类,在这个类中并没有太复杂的功能,主要的函数是init函数中,源码如下:

主要工作就是设置我们在web.xml中配置的contextConfigLocation属性,当然这个属性是springMVC文件的配置文件地址,当然也可以不用配置,使用默认名称加载。

initBeanWrapper 函数并没有具体实现

initServletBean()是模板方法,是在子类FrameworkServlet中实现的,接下来我们会详细分析,这样HttpServletBean的主体功能就介绍完了。

        public final void init() throws ServletException {
		if (logger.isDebugEnabled()) {
			logger.debug("Initializing servlet '" + getServletName() + "'");
		}

		// Set bean properties from init parameters.
		try {
			//获得web.xml中的contextConfigLocation配置属性,就是spring MVC的配置文件
			PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
			BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
			//获取服务器的各种信息
			ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
			bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
			//模板方法,可以在子类中调用,做一些初始化工作,bw代表DispatcherServelt
			initBeanWrapper(bw);
			//将配置的初始化值设置到DispatcherServlet中
			bw.setPropertyValues(pvs, true);
		}
		catch (BeansException ex) {
			logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
			throw ex;
		}

		// Let subclasses do whatever initialization they like.
		//模板方法,子类初始化的入口方法
		initServletBean();

		if (logger.isDebugEnabled()) {
			logger.debug("Servlet '" + getServletName() + "' configured successfully");
		}
	}

当然HttpServletBean还是提供了一些其他方法的,其实都是一些比较简单的get和set方法,就不做过多介绍了,HttpServletBean的完整源码如下:

/**
 *HttpServlet的一个简单扩展类
 */
@SuppressWarnings("serial")
public abstract class HttpServletBean extends HttpServlet
		implements EnvironmentCapable, EnvironmentAware {

	protected final Log logger = LogFactory.getLog(getClass());

	private final Set<String> requiredProperties = new HashSet<String>();

	private ConfigurableEnvironment environment;

	protected final void addRequiredProperty(String property) {
		this.requiredProperties.add(property);
	}
	@Override
	public final void init() throws ServletException {
		if (logger.isDebugEnabled()) {
			logger.debug("Initializing servlet '" + getServletName() + "'");
		}

		// Set bean properties from init parameters.
		try {
			//获得web.xml中的contextConfigLocation配置属性,就是spring MVC的配置文件
			PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
			BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
			//获取服务器的各种信息
			ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
			bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
			//模板方法,可以在子类中调用,做一些初始化工作,bw代表DispatcherServelt
			initBeanWrapper(bw);
			//将配置的初始化值设置到DispatcherServlet中
			bw.setPropertyValues(pvs, true);
		}
		catch (BeansException ex) {
			logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
			throw ex;
		}

		// Let subclasses do whatever initialization they like.
		//模板方法,子类初始化的入口方法
		initServletBean();

		if (logger.isDebugEnabled()) {
			logger.debug("Servlet '" + getServletName() + "' configured successfully");
		}
	}

	/**
	 * Initialize the BeanWrapper for this HttpServletBean,
	 * possibly with custom editors.
	 * <p>This default implementation is empty.
	 * @param bw the BeanWrapper to initialize
	 * @throws BeansException if thrown by BeanWrapper methods
	 * @see org.springframework.beans.BeanWrapper#registerCustomEditor
	 */
	protected void initBeanWrapper(BeanWrapper bw) throws BeansException {
	}

	//获取servletName
	@Override
	public final String getServletName() {
		return (getServletConfig() != null ? getServletConfig().getServletName() : null);
	}

	//获取ServletContext
	@Override
	public final ServletContext getServletContext() {
		return (getServletConfig() != null ? getServletConfig().getServletContext() : null);
	}

	protected void initServletBean() throws ServletException {
	}

	@Override
	public void setEnvironment(Environment environment) {
		Assert.isInstanceOf(ConfigurableEnvironment.class, environment);
		this.environment = (ConfigurableEnvironment) environment;
	}

	@Override
	public ConfigurableEnvironment getEnvironment() {
		if (this.environment == null) {
			this.environment = this.createEnvironment();
		}
		return this.environment;
	}

	protected ConfigurableEnvironment createEnvironment() {
		return new StandardServletEnvironment();
	}

	private static class ServletConfigPropertyValues extends MutablePropertyValues {

		public ServletConfigPropertyValues(ServletConfig config, Set<String> requiredProperties)
			throws ServletException {

			Set<String> missingProps = (requiredProperties != null && !requiredProperties.isEmpty()) ?
					new HashSet<String>(requiredProperties) : null;

			Enumeration<String> en = config.getInitParameterNames();
			while (en.hasMoreElements()) {
				String property = en.nextElement();
				Object value = config.getInitParameter(property);
				addPropertyValue(new PropertyValue(property, value));
				if (missingProps != null) {
					missingProps.remove(property);
				}
			}
			// Fail if we are still missing properties.
			if (missingProps != null && missingProps.size() > 0) {
				throw new ServletException(
					"Initialization from ServletConfig for servlet '" + config.getServletName() +
					"' failed; the following required properties were missing: " +
					StringUtils.collectionToDelimitedString(missingProps, ", "));
			}
		}
	}

}

SpringMVC源码分析--容器初始化(三)HttpServletBean的更多相关文章

  1. SpringMVC源码分析--容器初始化(四)FrameworkServlet

    在上一篇博客SpringMVC源码分析--容器初始化(三)HttpServletBean我们介绍了HttpServletBean的init函数,其主要作用是初始化了一下SpringMVC配置文件的地址 ...

  2. SpringMVC源码分析--容器初始化(五)DispatcherServlet

    上一篇博客SpringMVC源码分析--容器初始化(四)FrameworkServlet我们已经了解到了SpringMVC容器的初始化,SpringMVC对容器初始化后会进行一系列的其他属性的初始化操 ...

  3. springMVC源码分析--容器初始化(二)DispatcherServlet

    在上一篇博客springMVC源码分析--容器初始化(一)中我们介绍了spring web初始化IOC容器的过程,springMVC作为spring项目中的子项目,其可以和spring web容器很好 ...

  4. springMVC源码分析--容器初始化(一)ContextLoaderListener

    在spring Web中,需要初始化IOC容器,用于存放我们注入的各种对象.当tomcat启动时首先会初始化一个web对应的IOC容器,用于初始化和注入各种我们在web运行过程中需要的对象.当tomc ...

  5. springMVC源码分析--AbstractUrlHandlerMapping(三)

    上一篇博客springMVC源码分析--AbstractHandlerMapping(二)中我们介绍了AbstractHandlerMapping了,接下来我们介绍其子类AbstractUrlHand ...

  6. springMVC源码分析--SimpleControllerHandlerAdapter(三)

    上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...

  7. springMVC源码分析--DispatcherServlet请求获取及处理

    在之前的博客springMVC源码分析--容器初始化(二)DispatcherServlet中我们介绍过DispatcherServlet,是在容器初始化过程中出现的,我们之前也说过Dispatche ...

  8. springMVC源码分析--AbstractDetectingUrlHandlerMapping(五)

    上一篇博客springMVC源码分析--AbstractUrlHandlerMapping(三)中我们介绍了AbstractUrlHandlerMapping,主要介绍了一个handlerMap的ur ...

  9. springMVC源码分析--SimpleUrlHandlerMapping(四)

    上一篇博客springMVC源码分析--AbstractUrlHandlerMapping(三)中我们介绍了AbstractUrlHandlerMapping,主要介绍了一个handlerMap的ur ...

随机推荐

  1. c++中双冒号的作用

    双冒号(::)用法 参考链接:https://segmentfault.com/a/1190000000345680 1.表示“域操作符”例:声明了一个类A,类A里声明了一个成员函数void f(), ...

  2. button点击切换,获取按钮ID

    <!DOCTYPE html> <html> <head lang="zh-CN"> <meta charset="UTF-8& ...

  3. c# 虚拟路径转化为物理路径

    string strPhycicsPath= Server.MapPath(path);

  4. idea Library XXXXXXXX has broken classes paths

    点fix 然后全部 全部按- 删掉 一开始以为会影响很大 后来发现他地址错了都导不进 要是真要用到的时候也没用 还是要maven单独导进来

  5. Prometheus(转载)

    Prometheus 系统监控方案 一 https://www.cnblogs.com/vovlie/p/Prometheus_CONCEPTS.html 最近一直在折腾时序类型的数据库,经过一段时间 ...

  6. RabbitMQ环境安装

    1.安装erlang 语言环境 安装依赖 yum install ncurses-devel (如果没安装GCC,执行 yum install gcc或者:yum groupinstall " ...

  7. jupyter notebook 更换主题的方法

    参考 https://github.com/dunovank/jupyter-themes install with pip # install jupyterthemes pip install j ...

  8. C#利用Attribute实现简易AOP介绍

    首先看一段简单的代码: public partial class Form1 : Form { public Form1() { InitializeComponent(); } //来自UI层的调用 ...

  9. centos6 网卡配置,多IP设置

    ##云服务器 centos6网卡配置 #设置出口IP vim /etc/sysconfig/network-scripts/ifcfg-eth0DEVICE=seth0 #网卡名称 BOOTPROTO ...

  10. ng-book札记——路由

    路由的作用是分隔应用为不同的区块,每个区块基于匹配当前URL的规则. 路由可以分为服务端与客户端两种,服务端以Express.js为例: var express = require('express' ...