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

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-mybatis-spring-1.3.2.tar.gz

    在本项目中,Spring作为容器,管理着所有Bean的生命周期,通过XML配置文件或Java配置类来定义Bean的创建、初始化、销毁等过程。同时,Spring MVC作为其Web层组件,处理HTTP请求,实现业务逻辑和视图的解耦。 二、...

    Spring-MVC-DispatcherServlet-Example:Maven项目

    2. `webapp/WEB-INF/web.xml` - Web应用的部署描述符,定义DispatcherServlet的初始化参数。 3. `src/main/java/com/example/controllers` - 包含Controller类,处理HTTP请求。 4. `src/main/webapp/WEB-INF/views...

    Spring框架系列(13) - SpringMVC实现原理之DispatcherServlet的初始化过程.doc

    SpringMVC DispatcherServlet 初始化过程详解 DispatcherServlet 是 SpringMVC 框架中的核心组件,对于 SpringMVC 的请求处理和响应起着至关重要的作用。DispatcherServlet 的初始化过程是 SpringMVC 实现原理的...

    spring-framework-5.0.2.RELEASE-中文注释版-终极完美版.rar

    例如,`org.springframework.beans.factory.BeanFactory`接口定义了容器的基本操作,如获取Bean、初始化Bean等;`org.springframework.context.ApplicationContext`扩展了BeanFactory,提供了更多的企业级服务,如...

    spring-framework-4.1.6.RELEASE-schema.zip

    Schema文件定义了如何声明Bean,如定义Bean的属性、构造器、初始化方法、销毁方法等,以及如何声明Bean之间的依赖关系。 2. **oxm**(Object/XML Mapping):该模块提供了对象到XML的映射功能,使得Java对象可以...

    spring-framework-5.0.x.zip

    1. **Bean的生命周期管理**:研究BeanFactory和ApplicationContext如何创建、初始化和销毁Bean。 2. **AOP的实现**:了解切面是如何被编织到目标类中的,以及代理模式的应用。 3. **MVC框架**:探索...

    spring-framework-3.2.17.RELEASE-dist.zip

    在Spring 3.2.17中,开发者可以自定义bean的初始化和销毁方法,还可以利用生命周期回调接口控制bean的行为。此外,还支持基于注解的bean生命周期管理,如@PostConstruct和@PreDestroy。 7. **SpEL(Spring ...

    spring-learning-examples-master.zip

    5. **Spring Boot**:Spring Boot简化了Spring应用的初始化和配置,提供了一种快速开发新应用的方式。示例中可能包含使用@SpringBootApplication注解启动应用,以及如何配置自动配置的Bean。 6. **Sharding-Sphere*...

    官方原版源码spring-framework-5.0.13.RELEASE.zip

    1. **初始化流程**:从`org.springframework.context.support.ClassPathXmlApplicationContext`或`org.springframework.web.context.ContextLoader`开始,理解如何加载配置并创建Bean定义。 2. **依赖注入**:研究`...

    Spring-MVC-model

    - web.xml:配置DispatcherServlet和ContextLoaderListener,分别初始化Spring MVC和Spring应用上下文。 - spring-servlet.xml:定义Spring MVC的bean,如HandlerMapping、HandlerAdapter、ViewResolver等。 - ...

    Spring - 4 Web集成

    - 初始化ApplicationContext,并加载配置文件。 ##### 3. Spring MVC处理流程详解 - **流程**: 1. 用户发送HTTP请求到服务器。 2. DispatcherServlet接收到请求并将其委托给相应的控制器。 3. 控制器处理请求...

    Spring--ssm整合(分)

    7. **使用e3mall.sql**:这个文件可能是一个数据库初始化脚本,用于在项目启动时创建表结构和填充初始数据。在应用启动时,可以使用Spring的JdbcTemplate或JPA来执行这个脚本。 8. **测试**:最后,通过单元测试和...

    spring-framework-4.1.1.RELEASE-docs

    包括Bean的定义、配置、作用域、初始化和销毁过程。 2. AOP(Aspect Oriented Programming):Spring的AOP模块提供了面向切面编程的能力,允许开发者定义横切关注点,如日志、事务管理等,并将其与业务逻辑解耦。 ...

    spring-custom-master.7z

    自定义的注解可能会影响到bean的初始化、销毁方法,或者改变bean的生命周期行为。因此,熟悉`@PostConstruct`、`@PreDestroy`,以及`InitializingBean`、`DisposableBean`接口至关重要。 综上所述,"spring-custom-...

    spring基础教程-MVC详解

    - **web.xml**:传统方式下,需要在部署描述符中配置 DispatcherServlet 和 Spring MVC 的初始化参数。 - **Spring 配置文件**:定义 HandlerMapping(处理器映射器)和 HandlerAdapter(处理器适配器),以及视图...

    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-framework-4.3.17 源码包

    通过XML配置或注解方式,我们可以声明Bean及其依赖,容器负责创建和初始化Bean。在源码中,`org.springframework.beans.factory` 和 `org.springframework.context` 包下包含了IoC容器的主要实现。 2. AOP:AOP是...

    spring-framework-3.2.2.RELEASE

    - **容器(Container)**:Spring框架的核心是IoC容器,它负责创建对象并管理其生命周期,包括初始化、配置和装配对象。 2. **模块结构** - **Core Container**:包含Bean工厂和核心接口,如ApplicationContext,...

    zhouyu-spring-vip.rar

    Spring Boot是Spring生态体系的一个子项目,旨在简化Spring应用的初始搭建以及开发过程。它通过自动配置、起步依赖等特性,使开发者可以快速创建一个可运行的Spring应用。 3. Spring MVC详解: Spring MVC是...

    spring-mvc.docx

    1. **初始化 DispatcherServlet**:配置 DispatcherServlet 并指定其使用的 HandlerMapping 和 Controller 的位置。 2. **配置 HandlerMapping**:定义 Servlet 的映射规则,例如通过 URL 映射到特定的 Controller。...

Global site tag (gtag.js) - Google Analytics