基本概念
- Aware:
- 可感知的,XxxAware接口将包含一个setXxx方法,表示需要一个Xxx的实例,spring将通过setXxx方法将该实例注入;
- Capable:
- 可提供,XxxCapable接口将包含getXxx方法,表示XxxCapable接口的实现可提供一个Xxx的实例;
- Environment
- 在HttpServletBean中使用的Environment,封装了ServletContext、ServletConfig、JndiProperty、系统环境变量和系统属性;
- toString -> StandardServletEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[servletConfigInitParams,servletContextInitParams,jndiProperties,systemProperties,systemEnvironment]}
SpringMvc核心Servlet
- HttpServletBean【C - extends HttpServlet implements EnvironmentCapable,EnvironmentAware】
- init()-> 首先将Servlet中配置的参数使用BeanWrapper设置到Dispatcher中相关的属性;
- 调用模板方法initServletBean,子类就通过这个方法初始化;
- BeanWrapper:spring提供的一个用来操作javaBean属性的工具接口,默认实现BeanWrapperImpl,可以直接修改对象的属性;
- FrameworkServlet【C - extends HttpServletBean implements ApplicationContextAware】
- 由HttpServletBean可知,初始化方法应该是实现父类定义的模板方法initServletBean();
- 核心代码一:初始化WebApplicationContext
- 核心代码二:初始化FrameworkServlet,且initFrameworkServlet方法是模板方法;
- 结论,由上可知,FrameworkServlet的作用就是初始化了WebApplicationContext;
- initWebApplicationContext:
- 获取spring的根容器rootContext;
- 设置webApplicationContext属性并看情况调用onRefresh方法;
- 将webApplicationContext设置到ServletContext中;
- DispatcherServlet【C - extends FrameworkServlet】
- onRefresh是DispatcherServlet的入口方法, 简单调用了initStrategies方法,initStrategies中调用了9个初始化方法
- 只所以不直接在onRefresh中调用初始化方法,出于分层原因,onRefresh是用来刷新容器的initStrategies用来初始化一些策略组件。
- 原因一:如果想在onRefresh中添加别的功能,就会没有将其单独写一个方法出来逻辑清晰;
- 原因二:更重要的是,如果在别的地方也需要调用initStrategies(如,修改一些策略后热部署),就只能调用onRefresh,那样在onRefresh中添加新功能就麻烦了;
- 原因三:将initStrategies独立出来还可以被子覆盖,使用新的模式进行初始化;
- 综上,一切都是方便扩展;
- initStrategies方法:
- 调用9个初始化方法
- 初始化方法:先通过context.getBean获取,如果不存在(抛异常NoSuchBeanDefinitionException)则使用默认;
- 总结: DispatcherServlet的创建过程主要是对9个组件进行初始化;
- 多知道点:
- spring 的xml文件中通过命名空间配置的标签怎么解析
- 解析标签的类都放在META-INF下的spring.handlers文件中;
- 如mvc标签,spring-mvc-xxx.jar包下的META-INF/spring.handlers文件中指定了解析的类,即:org.springframework.web.servlet.config.MvcNamespaceHandler,该类内部将mvc:annotation-driven的解析交给了AnnotationDrivenBeanDefinitionParser
- 解析配置的组件继承结构:
- NamespaceHandler【I】
- init - 用来初始化自己;
- parse - 将配置的标签转换成所需要的BeanDefinition;
- decorate - 装饰的意思,对所在的BeanDefinition进行一些修改,用的较少;
- NamespaceHandlerSupport【C - implements NamespaceHandler】
- NamespaceHandler的默认实现,一般的NamespaceHandler都继承它;
- 该类没做具体工作,而是定义了三个处理器:
- parsers - 处理解析工作
- decorators - 处理标签类型
- attributeDecorators - 处理属性类型
- 结论: 要定义一个命名空间的解析器,只要在init中定义相应的以上三个处理器,并注册到NamespaceHandlerSupport上面;
- SimplePropertyNamespaceHandler【C - implements NamespaceHandler】
- SimpleConstructorNamespaceHandler【C - implements NamespaceHandler】
- MvcNamespaceHandler【C - extends NamespaceHandlerSupport】
配置Servlet时可以设置的一些初始化参数,总结:
- contextAttribute: 在ServletContext的属性中,要用作WebApplicationContext的属性名称;
- contextClass:创建WebApplicationContext的类型;
- contextConfigLocation: springMVC配置文件的位置;
- publishContext: 是否将webApplicationContext设置到ServletContext的属性;
本次学习小结:
- 以上都是有关springMVC的创建过程, 有三个类,
- HttpServletBean直接继承java-Servlet的HttpServlet,其作用是将Servlet中配置的参数设置到相应的属性;
- FrameworkServlet初始化了WebApplicationContext,用了三种方式,使用了Servlet中配置的一些参数:
- 分三个层次做了三件事,体现了spring的特点,结构简单(顶层设计好),实现复杂(功能比较多)
- DispatcherServlet初始化了自身的9个组件;
转载于:https://my.oschina.net/u/2407208/blog/782461