Spring知识整理
来源:互联网 发布:linux怎么上传压缩包 编辑:程序博客网 时间:2024/06/06 19:01
学习整理的笔记
一、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>com.paic.pafa.web.PafaDispatcherServlet</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(…)方法)
- 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中 - Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
- 根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
- ViewResolver 结合Model和View,来渲染视图
- 将渲染结果返回给客户端。
1.4 IOC 容器初始化过程
待整理
二、Spring bean生命周期
- Bean实例化与注入(Bean instantion and DI)
1. 扫描xml/注解,获取bean 定义
2. 实例化bean
3. 依赖注入
调用实现了Aware接口类的方法(check for spring Awares)
BeanNameAware.setBeanName(String beanId)
BeanFactoryAware.setBeanFactory(BeanFactory beanFactory)
: 可以用这个方法获取到其他BeanApplicationContextAware. setApplicationContext(ApplicationContext applicationContext)
:ApplicationContextAware传入Spring上下文,该方式同样可以实现BeanFactoryAware功能,但比BeanFactoryAware更好,因为ApplicationContext是BeanFactory的子接口,有更多的实现方法
Bean生命周期回调方法(bean creation lifecycle callback)
- BeanPostProcessor/@PostConstruct: BeanPostProcessor经常被用作是Bean内容的更改
postProcessBeforeInitialization(Object obj, String s)
initializingBean.afterPropertiesSet()
- init-method xml
- BeanPostProcessor/@PostConstruct
postAfterInitialization(Object obj, String s)
- BeanPostProcessor/@PostConstruct: BeanPostProcessor经常被用作是Bean内容的更改
- 使用bean
- 销毁bean
- @PreDestroy
执行注解标注的方法 - DisposableBean.destroy()
- destroy-method xml
- @PreDestroy
三、容器类
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
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()
方法,销毁实例。
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来配置实现。
- DelegatingFilterProxy
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
- Interceptor
以struts的拦截器为例,加载了struts.xml以后,初始化相应拦截器。当action请求来时调用intercept方法,服务器停止销毁interceptor
- Interceptor