1. 程式人生 > >菜鳥之路——Spring MVC(三)DispatcherServlet詳解

菜鳥之路——Spring MVC(三)DispatcherServlet詳解

/**
 * Simple extension of {@link javax.servlet.http.HttpServlet} which treats
 * its config parameters ({@code init-param} entries within the
 * {@code servlet} tag in {@code web.xml}) as bean properties.
 *
 * <p>A handy superclass for any type of servlet. Type conversion of config
 * parameters is automatic, with the corresponding setter method getting
 * invoked with the converted value. It is also possible for subclasses to
 * specify required properties. Parameters without matching bean property
 * setter will simply be ignored.
 *
 * <p>This servlet leaves request handling to subclasses, inheriting the default
 * behavior of HttpServlet ({@code doGet}, {@code doPost}, etc).
 *
 * <p>This generic servlet base class has no dependency on the Spring
 * {@link org.springframework.context.ApplicationContext} concept. Simple
 * servlets usually don't load their own context but rather access service
 * beans from the Spring root application context, accessible via the
 * filter's {@link #getServletContext() ServletContext} (see
 * {@link org.springframework.web.context.support.WebApplicationContextUtils}).
 *
 * <p>The {@link FrameworkServlet} class is a more specific servlet base
 * class which loads its own application context. FrameworkServlet serves
 * as direct base class of Spring's full-fledged {@link DispatcherServlet}.*/
  我們可以從HttpServletBean的繼承關係來分析它的作用:

  HttpServletBean extends HttpServlet
  implements EnvironmentCapable, EnvironmentAware

  1. 繼承了javax.servlet.http.HttpServlet

  簡單的說HttpServletBean是javax.servlet.http.HttpServlet類的簡單擴充套件,在web.xml檔案中<servlet>標籤的下一級標籤中通過<init-param>來配置該servlet的引數。例項如下:
<!-- This servlet must be loaded first to configure the log4j
     system and create the WebApplicationContext
     -->
    <servlet>
        <servlet-name>config</servlet-name>
        <servlet-class>org.springframework.framework.web.context.ContextLoaderServlet</servlet-class>
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>org.springframework.framework.web.context.XMLWebApplicationContext</param-value>           
        </init-param>    
        <init-param>
            <param-name>log4jPropertiesUrl</param-name>
            <param-value>/WEB-INF/log4j_PRODUCTION.properties</param-value>           
        </init-param>    
        <!-- This is essential -->
        <load-on-startup>1</load-on-startup>
      </servlet>
  2. 繼承了EnvironmentAware

  EnvironmentAware到底起了什麼作用呢?這需要我們首先了解一下Aware介面的作用:
/**
 * Marker superinterface indicating that a bean is eligible to be
 * notified by the Spring container of a particular framework object
 * through a callback-style method. Actual method signature is
 * determined by individual subinterfaces, but should typically
 * consist of just one void-returning method that accepts a single
 * argument.
 *
 * <p>Note that merely implementing {@link Aware} provides no default
 * functionality. Rather, processing must be done explicitly, for example
 * in a {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessor}.
 * Refer to {@link org.springframework.context.support.ApplicationContextAwareProcessor}
 * and {@link org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory}
 * for examples of processing {@code *Aware} interface callbacks.
 *
 * @author Chris Beams
 * @since 3.1
 */
public interface Aware {

}
  容器中定義的Bean一般不需要了解容器的狀態或者直接使用容器,但是在某些情況下,是需要在Bean中直接對IOC容器進行操作的,這時候,就需要在Bean中設定對容器的感知。Spring IOC容器也提供了該功能,它是通過特定的Aware介面來完成的。這個比較抽象,我們來從程式碼來理解吧:

  從spring-beans模組中我發現有三個實現了Aware介面,它們分別是:

BeanNameAware: Interface to be implemented by beans that want to be aware of their bean name in a bean factory. Note that it is not usually recommended that an object depend on its bean name, as this represents a potentially brittle dependence on external configuration, as well as a possibly unnecessary dependence on a Spring API.

BeanFactoryAware: Interface to be implemented by beans that wish to be aware of their owning {@link BeanFactory}.For example, beans can look up collaborating beans via the factory (Dependency Lookup). Note that most beans will choose to receive references to collaborating beans via corresponding bean properties or constructor arguments (Dependency Injection).

BeanClassLoaderAware: Callback that allows a bean to be aware of the bean {@link ClassLoader class loader}; that is, the class loader used by the present bean factory to load bean classes. This is mainly intended to be implemented by framework classes which have to pick up application classes by name despite themselves potentially being loaded from a shared class loader.

  上面三個介面分別實現了響應的set方法: