DispatcherServlet&Aware&Capable&Environment介绍

基本概念

  • 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】
          • 用于统一对通过p配置的参数进行解析;
        • SimpleConstructorNamespaceHandler【C - implements NamespaceHandler】
          • 用于统一对通过c配置的构造方法进行解析;
        • 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值