Spring知识整理

学习整理的笔记

一、Spring MVC 启动过程

SpringMVC启动过程详解

1.1 web 容器初始化过程

  1. 初始化监听器listener
  2. listener implement ServletContextListener, 则调用contextInitialized()
  3. 初始化filter,调用init()
  4. 按照<load-on-startup>顺序初始化servlet, 并调用init()

1.2 web.xml配置

<listener>
       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
复制代码
public class ContextLoaderListener extends ContextLoader implements ServletContextListener
复制代码

servlet和Filter初始化前和销毁后,都会给实现了servletContextListener接口的监听器发出相应的通知。
ContextLoadListener类用来创建Spring application context,并且将application context注册到servletContext里面去. 它读取web.xml中配置的context-param中的配置文件,提前在web容器初始化前准备业务对应的Application context;将创建好的Application context放置于ServletContext中,为springMVC部分的初始化做好准备

1.3 DispatchServlet初始化

DispatchServlet将web请求转发给controller层处理,起到控制器的作用

<servlet>
	<servlet-name>dispatcher</servlet-name>
	<servlet-class>xxx.DispatcherServlet</servlet-class>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/web-context.xml</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>
复制代码

上图是DispatchServlet类和ContextLoaderListener类的关系图。首先,用ContextLoaderListener初始化上下文,接着使用DispatchServlet来初始化WebMVC的上下文。

Spring工作流程描述

  1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获;

  2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;

  3. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。

    如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)

  4. 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作: HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
    数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
    数据格式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
    数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中

  5. Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;

  6. 根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;

  7. ViewResolver 结合Model和View,来渲染视图

  8. 将渲染结果返回给客户端。

1.4 IOC 容器初始化过程

待整理

二、Spring bean生命周期

  • Bean实例化与注入(Bean instantion and DI)

    1. 扫描xml/注解,获取bean 定义
    2. 实例化bean
    3. 依赖注入
  • 调用实现了Aware接口类的方法(check for spring Awares)

    1. BeanNameAware.setBeanName(String beanId)
    2. BeanFactoryAware.setBeanFactory(BeanFactory beanFactory): 可以用这个方法获取到其他Bean
    3. ApplicationContextAware. setApplicationContext(ApplicationContext applicationContext):ApplicationContextAware传入Spring上下文,该方式同样可以实现BeanFactoryAware功能,但比BeanFactoryAware更好,因为ApplicationContext是BeanFactory的子接口,有更多的实现方法
  • Bean生命周期回调方法(bean creation lifecycle callback)

    1. BeanPostProcessor/@PostConstruct: BeanPostProcessor经常被用作是Bean内容的更改 postProcessBeforeInitialization(Object obj, String s)
    2. initializingBean.afterPropertiesSet()
    3. init-method xml
    4. BeanPostProcessor/@PostConstruct postAfterInitialization(Object obj, String s)
  • 使用bean

  • 销毁bean

    1. @PreDestroy 执行注解标注的方法
    2. DisposableBean.destroy()
    3. destroy-method xml

三、容器类

3.1 扩展:ApplicationListener

那么每当在一个ApplicationEvent发布到 ApplicationContext时, 这个bean得到通知。其实这就是标准的Oberver设计模式

3.2 ApplicationContextAware

先要有spring容器

<!-- 初始化Spring容器,让Spring容器随Web应用的启动而自动启动 -->  
<listener>  
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
</listener>  
复制代码

再注册,将bean加入到容器中

<bean class="com.paic.papc.common.util.PapcApplicationUtils"/>
复制代码
public class PapcApplicationUtils implements ApplicationContextAware
复制代码

spring容器会自动把上下文环境对象调用ApplicationContextAware接口中的setApplicationContext方法,这个类就可以方便获得ApplicationContext中的所有bean。

3.3 BeanFactory

spring使用BeanFactory来实例化、配置和管理对象,但是它只是一个接口,里面有一个getBean()方法。我们一般都不直接用BeanFactory,而是用它的实现类ApplicationContext,这个类会自动解析我们配置的applicationContext.xml,然后根据我们配置的bean来new对象,将new好的对象放进一个Map中,键就是我们bean的id,值就是new的对象

3.4 Aware接口

如 BeanFactoryAware,MessageSourceAware,ApplicationContextAware 对于实现了这些Aware接口的bean,在实例化bean时Spring会帮我们注入对应的:BeanFactory, MessageSource,ApplicationContext的实例

3.5 Filter VS Intercepter VS listener

项目Filterintercepterlistener
原理filter接口中的doFilter回调函数,为处理链:chain.doFilter()为前后分界线基于Java反射机制
servlet容器依赖不依赖, 与servlet无关依赖
作用域所有配置的请求,包括图片页面等只对Action请求, 在action之前开始,在action完成后结束
访问上下文,栈值对象不可以可以
生命周期只在容器初始化时初始化一次 inti()方法,web应用停止时才销毁多次调用只在容器初始化时初始化一次 ,web应用停止时才销毁
执行顺序按Filter在web.xml中的配置顺序
场景过滤字符编码,登录验证面向切面编程, 比如动态代理就是拦截器的简单实现监听application,session,request对象的活动

servlet、filter、listener是配置到web.xml中
web.xml 的加载顺序是:context-param -> listener -> filter -> servlet -> spring 所以如果过滤器中要使用到 bean,可以将spring 的加载 改成 Listener的方式, 则spring bean可以先通过listener提前加载了

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
复制代码

interceptor不配置到web.xml中, spring的拦截器配置到spring.xml中(cloud_core是配置在biz-context.xml 和web-context.xml )

  1. servlet
    在服务器的运行生命周期为,在第一次请求(或其实体被内存垃圾回收后再被访问)时被加载并执行一次初始化方法,跟着执行正式运行方法,之后会被常驻并每次被请求时直接执行正式运行方法,直到服务器关闭或被清理时执行一次销毁方法后实体销毁。
    (1)、装入:启动服务器时加载Servlet的实例;
    (2)、初始化:web服务器启动时或web服务器接收到请求时,或者两者之间的某个时刻启动。初始化工作有init()方法负责执行完成;
    (3)、调用:从第一次到以后的多次访问,都是只调用doGet()doPost()方法;
    (4)、销毁:停止服务器时调用destroy()方法,销毁实例。

  2. filter
    (1)、启动服务器时加载过滤器的实例,并调用init()方法来初始化实例;
    (2)、每一次请求时都只调用方法doFilter()进行处理;
    (3)、停止服务器时调用destroy()方法,销毁实例。 filter执行是按照web.xml配置的filter-mapping先后顺序进行执行,所以应该先进行编码处理,写在前面 若把filter的具体实现类写入到<filter-class>中.那么就默认是由容器而非spring管理,就不能直接注入spring实例
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

    • DelegatingFilterProxy
      DelegatingFilterProxy就是一个对于servlet filter的代理,用这个类的好处主要是通过Spring容器来管理servlet filter的生命周期,如果filter中需要一些Spring容器的实例,可以通过spring直接注入,另外读取一些配置文件这些便利的操作都可以通过Spring来配置实现。
  3. listener
    实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。
    Listener的生命周期是由servlet容器(例如tomcat)管理的,而servlet容器并不认得@Autowired注解,因此导致实例注入失败. 而spring容器中的bean的生命周期是由spring容器管理的。
    只需在web.xml中先配置初始化spring容器的Listener,然后再配置自己的Listener,在自己的Listener中初始化spring的bean
    现在监听器使用spring初始化的内容(即bean)

  • 声明listener
<listener>  
  <listener-class>xxx.SubmitListener</listener-class> 
 </listener>
复制代码
  • 实现listener
  1. Interceptor
    以struts的拦截器为例,加载了struts.xml以后,初始化相应拦截器。当action请求来时调用intercept方法,服务器停止销毁interceptor
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值