SpringMVC原始碼分析--容器初始化(三)HttpServletBean
阿新 • • 發佈:2019-01-10
在上一篇部落格 springMVC原始碼分析--容器初始化(二)DispatcherServlet中,我們隊SpringMVC整體生命週期有一個簡單的說明,並沒有進行詳細的原始碼分析,接下來我們會根據部落格中提供的springMVC的生命週期圖來詳細的對SpringMVC的相關原始碼進行分析。
在上一篇部落格中我們瞭解到,SpringMVC初始化配置是在父類HttpServletBean的init方法中,其實HttServletBean是一個比較簡單的類,在這個類中並沒有太複雜的功能,主要的函式是init函式中,原始碼如下:
主要工作就是設定我們在web.xml中配置的contextConfigLocation屬性,當然這個屬性是springMVC檔案的配置檔案地址,當然也可以不用配置,使用預設名稱載入。
initBeanWrapper 函式並沒有具體實現
initServletBean()是模板方法,是在子類FrameworkServlet中實現的,接下來我們會詳細分析,這樣HttpServletBean的主體功能就介紹完了。
當然HttpServletBean還是提供了一些其他方法的,其實都是一些比較簡單的get和set方法,就不做過多介紹了,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"); } }
/** *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, ", ")); } } } }