说明
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>
类图
- HttpServletBean ,负责将 ServletConfig 设置到当前 Servlet 对象中。
- FrameworkServlet ,负责初始化 Spring Servlet WebApplicationContext 容器。
- 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>
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()); } }