Spring-DispatcherServlet初始化详解

Spring-DispatcherServlet请求处理: http://donald-draper.iteye.com/blog/2325415
Spring的DefaultAnnotationHandlerMapping详解: http://donald-draper.iteye.com/blog/2325453
SpringMVC在web.xml中的配置一般为
<servlet>
    <servlet-name>springMvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring/ApplicationContext-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springMvc</servlet-name>
    <url-pattern>/</url-pattern>
 </servlet-mapping>

下面,我们来看看DispatcherServlet做了些什么
//DispatcherServlet
 public class DispatcherServlet extends FrameworkServlet
{
}

从DispatcherServlet我们看不到任何入口再来看FrameworkServlet
public abstract class FrameworkServlet extends HttpServletBean
    implements ApplicationContextAware
{
 public FrameworkServlet(WebApplicationContext webApplicationContext)
    {
        contextClass = DEFAULT_CONTEXT_CLASS;
        contextInitializers = new ArrayList();
        publishContext = true;
        publishEvents = true;
        threadContextInheritable = false;
        dispatchOptionsRequest = false;
        dispatchTraceRequest = false;
        webApplicationContextInjected = false;
        refreshEventReceived = false;
        this.webApplicationContext = webApplicationContext;
    }
    //而FrameworkServlet也没有任何入口,可以查看源头
      public void setApplicationContext(ApplicationContext applicationContext)
    {
        if(webApplicationContext == null && (applicationContext instanceof WebApplicationContext))
        {
            webApplicationContext = (WebApplicationContext)applicationContext;
            webApplicationContextInjected = true;
        }
    }
    public static final String DEFAULT_NAMESPACE_SUFFIX = "-servlet";
    public static final Class DEFAULT_CONTEXT_CLASS = org/springframework/web/context/support/XmlWebApplicationContext;
    public static final String SERVLET_CONTEXT_PREFIX = (new StringBuilder()).append(org/springframework/web/servlet/FrameworkServlet.getName()).append(".CONTEXT.").toString();
    private static final String INIT_PARAM_DELIMITERS = ",; \t\n";
    private String contextAttribute;
    private Class contextClass;
    private String contextId;
    private String namespace;
    private String contextConfigLocation;
    private final ArrayList contextInitializers;
    private String contextInitializerClasses;
    private boolean publishContext;
    private boolean publishEvents;
    private boolean threadContextInheritable;
    private boolean dispatchOptionsRequest;
    private boolean dispatchTraceRequest;
    private WebApplicationContext webApplicationContext;
    private boolean webApplicationContextInjected;
    private boolean refreshEventReceived;
}

再看HttpServletBean,仍然找不到入口
public abstract class HttpServletBean extends HttpServlet
    implements EnvironmentCapable, EnvironmentAware
{
   
    protected final Log logger = LogFactory.getLog(getClass());
    private final Set requiredProperties = new HashSet();
    private ConfigurableEnvironment environment;
}

再看HttpServlet,还是没有发现源头
public abstract class HttpServlet extends GenericServlet
    implements Serializable
{
    private static final String METHOD_DELETE = "DELETE";
    private static final String METHOD_HEAD = "HEAD";
    private static final String METHOD_GET = "GET";
    private static final String METHOD_OPTIONS = "OPTIONS";
    private static final String METHOD_POST = "POST";
    private static final String METHOD_PUT = "PUT";
    private static final String METHOD_TRACE = "TRACE";
    private static final String HEADER_IFMODSINCE = "If-Modified-Since";
    private static final String HEADER_LASTMOD = "Last-Modified";
    private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings";
    private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings");
}

再看GenericServlet
public abstract class GenericServlet
    implements Servlet, ServletConfig, Serializable
{
 //实现了Servlet的init(ServletConfig config)的方法,servlet在初始化时,回调用此函数
 public void init(ServletConfig config)
        throws ServletException
    {
        this.config = config;
	//调用初始化方法这是我们要追溯的地方
        init();
    }
    public void init()
        throws ServletException
    {
    }
}

往会找实现init()方法的HttpServletBean
public final void init()
        throws ServletException
    {
        if(logger.isDebugEnabled())
            logger.debug((new StringBuilder()).append("Initializing servlet '").append(getServletName()).append("'").toString());
        try
        {
            org.springframework.beans.PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), requiredProperties);
            BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
            org.springframework.core.io.ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
            bw.registerCustomEditor(org/springframework/core/io/Resource, new ResourceEditor(resourceLoader, getEnvironment()));
            initBeanWrapper(bw);
            bw.setPropertyValues(pvs, true);
        }
	//关键在这一步,初始化Servletbean
        initServletBean();
    }

查看FrameworkServlet的initServletBean方法
protected final void initServletBean()
        throws ServletException
    {
        getServletContext().log((new StringBuilder()).append("Initializing Spring FrameworkServlet '").append(getServletName()).append("'").toString());
        if(logger.isInfoEnabled())
            logger.info((new StringBuilder()).append("FrameworkServlet '").append(getServletName()).append("': initialization started").toString());
        long startTime = System.currentTimeMillis();
        try
        {
	    //初始化webApplicationContext,关键在这
            webApplicationContext = initWebApplicationContext();
	    //初始化框架路由,实际此方法为空体,给子类扩展
            initFrameworkServlet();
        }
        if(logger.isInfoEnabled())
        {
            long elapsedTime = System.currentTimeMillis() - startTime;
            logger.info((new StringBuilder()).append("FrameworkServlet '").append(getServletName()).append("': initialization completed in ").append(elapsedTime).append(" ms").toString());
        }
    }

查看initWebApplicationContext方法
protected WebApplicationContext initWebApplicationContext()
    {
        if(!refreshEventReceived)
	    //刷新web上下文
            onRefresh(wac);
        return wac;
    }

而FrameworkServlet的onRefresh方法为空,给子类扩展
protected void onRefresh(ApplicationContext applicationcontext)
    {
    }

我们来看DispatcherServlet
public class DispatcherServlet extends FrameworkServlet
{
 public DispatcherServlet(WebApplicationContext webApplicationContext)
    {
        super(webApplicationContext);
        detectAllHandlerMappings = true;
        detectAllHandlerAdapters = true;
        detectAllHandlerExceptionResolvers = true;
        detectAllViewResolvers = true;
        throwExceptionIfNoHandlerFound = false;
        cleanupAfterInclude = true;
    }
    //刷新上下文
     protected void onRefresh(ApplicationContext context)
    {
        //委托给initStrategies
        initStrategies(context);
    }
    //初始化文件上传,本地化,url映射
    protected void initStrategies(ApplicationContext context)
    {
        //初始化文件上传解处理器
        initMultipartResolver(context);
	 //初始化本地化处理器
        initLocaleResolver(context);
	//初始化主题处理器
        initThemeResolver(context);
        initHandlerMappings(context);
        initHandlerAdapters(context);
        initHandlerExceptionResolvers(context);
        initRequestToViewNameTranslator(context);
        initViewResolvers(context);
        initFlashMapManager(context);
    }
    //初始化文件上传解处理器
      private void initMultipartResolver(ApplicationContext context)
    {
        try
        {
            multipartResolver = (MultipartResolver)context.getBean("multipartResolver", org/springframework/web/multipart/MultipartResolver);
        }
    }
    //初始化本地化处理器
    private void initLocaleResolver(ApplicationContext context)
    {
        try
        {
            localeResolver = (LocaleResolver)context.getBean("localeResolver", org/springframework/web/servlet/LocaleResolver);          
        }
       
    }
     //初始化主题处理器
    private void initThemeResolver(ApplicationContext context)
    {
        try
        {
            themeResolver = (ThemeResolver)context.getBean("themeResolver", org/springframework/web/servlet/ThemeResolver);            
        }
      
    }
    //初始化控制器映射
     private void initHandlerMappings(ApplicationContext context)
    {
        handlerMappings = null;
        if(detectAllHandlerMappings)
        {
            Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, org/springframework/web/servlet/HandlerMapping, true, false);
            if(!matchingBeans.isEmpty())
            {
	       //List<HashMap<String,HandlerMapping>>,Key为beanName,value值为HandlerMapping实例
                handlerMappings = new ArrayList(matchingBeans.values());
                OrderComparator.sort(handlerMappings);
            }
        } 
    }
    //初始化控制器方法适配器
      private void initHandlerAdapters(ApplicationContext context)
    {
        handlerAdapters = null;
        if(detectAllHandlerAdapters)
        {
            Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, org/springframework/web/servlet/HandlerAdapter, true, false);
            if(!matchingBeans.isEmpty())
            {
                //List<HashMap<String,HandlerAdapter>>,Key为beanName,value值为HandlerAdapter实例
                handlerAdapters = new ArrayList(matchingBeans.values());
                OrderComparator.sort(handlerAdapters);
            }
        }
    }
    public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";
    public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";
    public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";
    public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";
    public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter";
    public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver";
    public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator";
    public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";
    public static final String FLASH_MAP_MANAGER_BEAN_NAME = "flashMapManager";
    public static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = (new StringBuilder()).append(org/springframework/web/servlet/DispatcherServlet.getName()).append(".CONTEXT").toString();
    public static final String LOCALE_RESOLVER_ATTRIBUTE = (new StringBuilder()).append(org/springframework/web/servlet/DispatcherServlet.getName()).append(".LOCALE_RESOLVER").toString();
    public static final String THEME_RESOLVER_ATTRIBUTE = (new StringBuilder()).append(org/springframework/web/servlet/DispatcherServlet.getName()).append(".THEME_RESOLVER").toString();
    public static final String THEME_SOURCE_ATTRIBUTE = (new StringBuilder()).append(org/springframework/web/servlet/DispatcherServlet.getName()).append(".THEME_SOURCE").toString();
    public static final String INPUT_FLASH_MAP_ATTRIBUTE = (new StringBuilder()).append(org/springframework/web/servlet/DispatcherServlet.getName()).append(".INPUT_FLASH_MAP").toString();
    public static final String OUTPUT_FLASH_MAP_ATTRIBUTE = (new StringBuilder()).append(org/springframework/web/servlet/DispatcherServlet.getName()).append(".OUTPUT_FLASH_MAP").toString();
    public static final String FLASH_MAP_MANAGER_ATTRIBUTE = (new StringBuilder()).append(org/springframework/web/servlet/DispatcherServlet.getName()).append(".FLASH_MAP_MANAGER").toString();
    public static final String PAGE_NOT_FOUND_LOG_CATEGORY = "org.springframework.web.servlet.PageNotFound";
    private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties";
    protected static final Log pageNotFoundLogger = LogFactory.getLog("org.springframework.web.servlet.PageNotFound");
    private static final Properties defaultStrategies;
    private boolean detectAllHandlerMappings;
    private boolean detectAllHandlerAdapters;
    private boolean detectAllHandlerExceptionResolvers;
    private boolean detectAllViewResolvers;
    private boolean throwExceptionIfNoHandlerFound;
    private boolean cleanupAfterInclude;
    private MultipartResolver multipartResolver;
    private LocaleResolver localeResolver;
    private ThemeResolver themeResolver;
    private List handlerMappings;//List<HashMap<String,HandlerMapping>>,Key为beanName,value值为HandlerMapping实例
    private List handlerAdapters;//List<HashMap<String,HandlerAdapter>>,Key为beanName,value值为HandlerAdapter实例
    private List handlerExceptionResolvers;
    private RequestToViewNameTranslator viewNameTranslator;
    private FlashMapManager flashMapManager;
    private List viewResolvers;

    static 
    {
        try
        {
	    //加载默认配置文件
            ClassPathResource resource = new ClassPathResource("DispatcherServlet.properties", org/springframework/web/servlet/DispatcherServlet);
            defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
        }
    }

}

//bean工厂类
public abstract class BeanFactoryUtils
{
//获取所有带@Controller注解的bean映射
public static Map beansOfTypeIncludingAncestors(ListableBeanFactory lbf, Class type, boolean includeNonSingletons, boolean allowEagerInit)
        throws BeansException
    {
       
        Map result = new LinkedHashMap(4);
	//从容器中获取指定类型的bean
        result.putAll(lbf.getBeansOfType(type, includeNonSingletons, allowEagerInit));
	//获取父容器中的bean
        if(lbf instanceof HierarchicalBeanFactory)
        {
            HierarchicalBeanFactory hbf = (HierarchicalBeanFactory)lbf;
            if(hbf.getParentBeanFactory() instanceof ListableBeanFactory)
            {
                Map parentResult = beansOfTypeIncludingAncestors((ListableBeanFactory)hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
                Iterator iterator = parentResult.entrySet().iterator();
                do
                {
                    if(!iterator.hasNext())
                        break;
                    java.util.Map.Entry entry = (java.util.Map.Entry)iterator.next();
                    String beanName = (String)entry.getKey();
                    if(!result.containsKey(beanName) && !hbf.containsLocalBean(beanName))
                        result.put(beanName, entry.getValue());
                } while(true);
            }
        }
        return result;
    }
 
}

//静态bean容器
public class StaticListableBeanFactory
    implements ListableBeanFactory
{
  public Map getBeansOfType(Class type)
        throws BeansException
    {
        return getBeansOfType(type, true, true);
    }
    //获取容器类型为type的bean
    public Map getBeansOfType(Class type, boolean includeNonSingletons, boolean includeFactoryBeans)
        throws BeansException
    {
        Map matches = new HashMap();
        Iterator iterator = beans.entrySet().iterator();
        do
        {
            if(!iterator.hasNext())
                break;
            java.util.Map.Entry entry = (java.util.Map.Entry)iterator.next();
            String beanName = (String)entry.getKey();
            Object beanInstance = entry.getValue();
            if((beanInstance instanceof FactoryBean) && !isFactoryType)
            {
                if(includeFactoryBeans)
                {
                    FactoryBean factory = (FactoryBean)beanInstance;
                    Class objectType = factory.getObjectType();
                    if((includeNonSingletons || factory.isSingleton()) && objectType != null && (type == null || type.isAssignableFrom(objectType)))
                        matches.put(beanName, getBean(beanName, type));
                }
            } else
            if(type == null || type.isInstance(beanInstance))
            {
                if(isFactoryType)
                    beanName = (new StringBuilder()).append("&").append(beanName).toString();
                matches.put(beanName, beanInstance);
            }
        } while(true);
        return matches;
    }
       //获取beanName为name类型为requiredType的bean
     public Object getBean(String name, Class requiredType)
        throws BeansException
    {
        Object bean = getBean(name);
        if(requiredType != null && !requiredType.isAssignableFrom(bean.getClass()))
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        else
            return bean;
    }
    //获取beanName为name的bean
     public Object getBean(String name)
        throws BeansException
    {
        String beanName;
        Object bean;
        beanName = BeanFactoryUtils.transformedBeanName(name);
        bean = beans.get(beanName);
	if(!(bean instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name))
            break MISSING_BLOCK_LABEL_130;
	//工厂bean则返回getObject
        return ((FactoryBean)bean).getObject();
        return bean;
    }
}

以上是DispatcherServlet的初始化,主要有初始化文件上传处理器,本地化处理器,
主题处理器,异常处理器,以及Controller映射处理器HandlerMappings和Method适配器HandlerAdapters。

猜你喜欢

转载自donald-draper.iteye.com/blog/2325394