`
Donald_Draper
  • 浏览: 951863 次
社区版块
存档分类
最新评论

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。
0
0
分享到:
评论

相关推荐

    Spring-Reference_zh_CN(Spring中文参考手册)

    3.3.5. 延迟初始化bean 3.3.6. 自动装配(autowire)协作者 3.3.6.1. 设置Bean使自动装配失效 3.3.7. 依赖检查 3.3.8. 方法注入 3.3.8.1. Lookup方法注入 3.3.8.2. 自定义方法的替代方案 3.4. bean的作用域 3.4.1. ...

    Spring MVC之DispatcherServlet详解_动力节点Java学院整理

    DispatcherServlet是前端控制器设计模式的实现,提供Spring Web MVC的集中访问点,而且负责职责的分派,而且与Spring IoC容器无缝集成,从而可以获得Spring的所有好处。 具体请参考第二章的图2-1。  ...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (1)

    8.4.3 改变初始化和销毁方式 8.4.4 改变异常处理的方式 8.5 小结 第九章 CVS使用指南 9.1 CVS介绍 9.1.1 CVS简介 9.1.2 为什么要使用CVS 9.2 建立CVS的开发环境 9.2.1 下载CVS 9.2.2 配置CVS 9.3 CVS的使用方法 ...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (3)

    8.4.3 改变初始化和销毁方式 8.4.4 改变异常处理的方式 8.5 小结 第九章 CVS使用指南 9.1 CVS介绍 9.1.1 CVS简介 9.1.2 为什么要使用CVS 9.2 建立CVS的开发环境 9.2.1 下载CVS 9.2.2 配置CVS 9.3 CVS的使用方法 ...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (2)

    8.4.3 改变初始化和销毁方式 8.4.4 改变异常处理的方式 8.5 小结 第九章 CVS使用指南 9.1 CVS介绍 9.1.1 CVS简介 9.1.2 为什么要使用CVS 9.2 建立CVS的开发环境 9.2.1 下载CVS 9.2.2 配置CVS 9.3 CVS的使用方法 ...

    spring chm文档

    3.3.5. 延迟初始化bean 3.3.6. 自动装配(autowire)协作者 3.3.7. 依赖检查 3.3.8. 方法注入 3.4. bean的作用域 3.4.1. Singleton作用域 3.4.2. Prototype作用域 3.4.3. 其他作用域 3.4.4. 自定义作用域 ...

    Spring中文帮助文档

    3.3.4. 延迟初始化bean 3.3.5. 自动装配(autowire)协作者 3.3.6. 依赖检查 3.3.7. 方法注入 3.4. Bean的作用域 3.4.1. Singleton作用域 3.4.2. Prototype作用域 3.4.3. Singleton beans和prototype-bean的...

    Spring API

    3.3.4. 延迟初始化bean 3.3.5. 自动装配(autowire)协作者 3.3.6. 依赖检查 3.3.7. 方法注入 3.4. Bean的作用域 3.4.1. Singleton作用域 3.4.2. Prototype作用域 3.4.3. Singleton beans和prototype-bean的...

    Spring Web MVC入门教程

    包括:功能、配置、上下文关系、初始化顺序等 第三章:注解式控制器开发详解 包括:注解式开发HelloWorld、处理器定义、请求映射、REST风格支持、请求数据映射、数据绑定等诸多内容 第四章:数据类型转换 包括:...

    Spring 2.0 开发参考手册

    3.3.5. 延迟初始化bean 3.3.6. 自动装配(autowire)协作者 3.3.7. 依赖检查 3.3.8. 方法注入 3.4. bean的作用域 3.4.1. Singleton作用域 3.4.2. Prototype作用域 3.4.3. 其他作用域 3.4.4. 自定义作用域 ...

    《程序天下:J2EE整合详解与典型案例》光盘源码

    8.4.3 改变初始化和销毁方式 8.4.4 改变异常处理的方式 8.5 小结 第九章 CVS使用指南 9.1 CVS介绍 9.1.1 CVS简介 9.1.2 为什么要使用CVS 9.2 建立CVS的开发环境 9.2.1 下载CVS 9.2.2 配置CVS 9.3 CVS的使用方法 ...

    看透springMvc源代码分析与实践

    13.5.1 初始化Model192 13.5.2 更新Model197 13.6 ServletInvocableHandlerMethod199 13.6.1 HandlerMethod199 13.6.2 InvocableHandlerMethod203 13.6.3 ServletInvocableHandler-Method205 13.7 ...

    JAVA核心知识点整理(有效)

    1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ........................

Global site tag (gtag.js) - Google Analytics