SpringMVC源码阅读-Servlte WebApplicationContext初始化(二)

说明

spring mvc 入口是通过配置Servlte来作为框架入口。servlte可以配置多个,每个Servlte都会初始化一个WebApplicationContext parent为root

配置例子

<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 可以自定义servlet.xml配置文件的位置和名称,默认为WEB-INF目录下,名称为[<servlet-name>]-servlet.xml,如spring-servlet.xml
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-servlet.xml</param-value> // 默认
    </init-param>
    -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet>
    <servlet-name>spring2</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 可以自定义servlet.xml配置文件的位置和名称,默认为WEB-INF目录下,名称为[<servlet-name>]-servlet.xml,如spring-servlet.xml
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-servlet.xml</param-value> // 默认
    </init-param>
    -->
    <load-on-startup>2</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>*/.springDo</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>spring2</servlet-name>
    <url-pattern>*/.spring2Do</url-pattern>
  </servlet-mapping>

类图

  1.  HttpServletBean ,负责将 ServletConfig 设置到当前 Servlet 对象中。
  2. FrameworkServlet ,负责初始化 Spring Servlet WebApplicationContext 容器。
  3. DispatcherServlet ,负责初始化 Spring MVC 的各个组件,以及处理客户端的请求。
 public final void init() throws ServletException {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Initializing servlet '" + this.getServletName() + "'");
        }

        try {
            /**
             * <1>
             * 将DispatcherServlet配置的 <init-param> 封装到PropertyValues
             */
            PropertyValues pvs = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig(), this.requiredProperties);
            /**
             * <2></>这里this 是DispatcherServlet  将他通过BeanWrapper 对象
             * beanWrapper是 spring框架内部操作java Bean的代理对象
             */
            BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
            ResourceLoader resourceLoader = new ServletContextResourceLoader(this.getServletContext());
            //<2> 注册属性编辑器  暂时不知道干嘛的 需要读了spring源码
            bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.getEnvironment()));
            //空实现 模板方法 需要子类实现可以做一些初始化操作
            this.initBeanWrapper(bw);
            //将pvs注入到BeanWrapper 这个也是代理的原因
            bw.setPropertyValues(pvs, true);
        } catch (BeansException var4) {
            this.logger.error("Failed to set bean properties on servlet '" + this.getServletName() + "'", var4);
            throw var4;
        }
        //空实现 需要子类实现 进行后续初始化操作
        this.initServletBean();
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Servlet '" + this.getServletName() + "' configured successfully");
        }

    }

HttpServletBean

org.springframework.web.servlet.HttpServletBean#init

public final void init() throws ServletException {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Initializing servlet '" + this.getServletName() + "'");
        }
        try {
            /**
             * <1>
             * 将DispatcherServlet配置的 <init-param> 封装到PropertyValues
             */
            PropertyValues pvs = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig(), this.requiredProperties);
            /**
             * <2></>这里this 是DispatcherServlet  将他通过BeanWrapper 对象
             * beanWrapper是 spring框架内部操作java Bean的代理对象
             */
            BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
            ResourceLoader resourceLoader = new ServletContextResourceLoader(this.getServletContext());
            //<2> 注册属性编辑器  暂时不知道干嘛的 需要读了spring源码
            bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.getEnvironment()));
            //空实现 模板方法 需要子类实现可以做一些初始化操作
            this.initBeanWrapper(bw);
            //将pvs注入到BeanWrapper 这个也是代理的原因
            bw.setPropertyValues(pvs, true);
        } catch (BeansException var4) {
            this.logger.error("Failed to set bean properties on servlet '" + this.getServletName() + "'", var4);
            throw var4;
        }
        //空实现 需要子类实现 进行后续初始化操作
        this.initServletBean();
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Servlet '" + this.getServletName() + "' configured successfully");
        }

    }

<2>beanwapper的简单使用方式

public class User {
    String userName;
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
}
public class BeanWrapperTest {
    public static void main(String[] args) {
        User user = new User();
        BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(user);
        bw.setPropertyValue("userName", "张三");
        System.out.println(user.getUserName());
        PropertyValue value = new PropertyValue("userName", "李四");
        bw.setPropertyValue(value);
        System.out.println(user.getUserName()); 
    }
}

猜你喜欢

转载自www.cnblogs.com/LQBlog/p/12191970.html