Spring
文章目录
- Spring
- **三.使用Spring框架的好处?**
- **一.Spring IOC原理,实现,优点**
- 如何理解IOC和DI
- **BeanFactory和ApplicationContext区别:**
- Spring提供了哪些配置方式
- 将一个类声明为Spring的bean有哪些注解
- Spring支持几种bean scope
- Spring bean的生命周期
- 什么是spring内部的bean
- 什么是spring bean装配
- Spring中出现同名的bean怎么办
- Spring怎么解决循环依赖
- Spring 中单例的bean的线程安全问题
- Spring AOP
- Spring 框架用到的设计模式
- Spring事务实现方式
- Spring 事务定义的传播规则
- Spring MVC流程
- @Controller注解
- @RequestMapping
- @RestController和@Controller区别
- @RequestMapping和@GetMapping区别
- 返回JSON格式使用什么注解
- **五.Spring的@Transactional如何实现的**
- **六.Spring Boot**
- **Spring Boot的核心注解是哪个?它主要由哪几个注解组成的?**
- **SpringBoot自动配置原理是什么?**
- **如何使用Spring Boot实现异常处理?**
- 保护Spring Boot应用有哪些方法
- **七.Spring,Spring MVC,Spring Boot关系**
- **八.MyBatis**
- 九.Spring事务,传播机制
- (一)Spring事务三种声明方式
- (二)Spring事务管理接口
- 十.Spring Boot注解
- 十一.Spring MVC流程
三.使用Spring框架的好处?
1.Spring是轻量级的
2.IOC的优点
3.AOP的优点
4.包含并管理对象的生命周期和配置
一.Spring IOC原理,实现,优点
原理:
IOC就是控制反转,把创建对象的控制权转移给Spring框架进行管理,并由Spring根据配置文件去创建实例和管理各个实例之间的依赖关系,以前创建对象的主动权和时机都是由自己把控的,IOC让对象的创建不用new去实现了,可以由spring自动生产,使用java的反射机制,根据配置文件在运行时动态的去创建对象以及管理对象,并调用对象的方法的。
比如说对象A要操作数据库,有了Spring我们就只需要告诉Spring,A中需要一个连接,至于这个连接什么时候构造,怎么构造,A不需要知道,Spring会在适当的时候构造一个连接,然后注射到A中,这样就完成了各个对象之间的控制
Spring IOC优点:
1.可以更灵活的管理对象(通过Spring容器来控制)
2.降低耦合度(通过工厂模式)
实现:
在初始化一个Spring容器时,Spring会去解析指定的xml文件,当解析到其中的标签时,会根据该标签中的class属性指定的类的全路径名,
通过反射创建该类的对象,并将该对象存入内置的Map中管理。其中键就是该标签的id值,值就是该对象。
之后,当通过getBean方法来从容器中获取对象时,其实就是根据传入的条件在内置的Map中寻找是否有匹配的键值,如果有则将该键值对中保存的对象返回,如果没有匹配到则抛出异常。
什么是依赖注入,有多少种方式完成依赖注入
依赖注入就是不必创建对象,但需要描述怎么创建;不是直接在代码中将组件和服务连接在一起,而是描述配置文件中哪些组件需要哪些服务,由IOC容器把他们装配到一起
Spring的IOC有三种注入方式 :
1.构造器注入
2.setter方法注入
3.根据注解注入
构造器注入和setter注入的区别
构造器注入中任意修改都要去创建新的实例,对于依赖关系无需变化的注入,尽量采用构造器,设置很多属性的也可以用构造器;而其他的依赖关系的注入,可以采用setter注入,设置少量属性的可以用setter。
如何理解IOC和DI
BeanFactory和ApplicationContext区别:
BeanFactory:
BeanFactory是spring中比较原始的接口。因为比较古老,所以BeanFactory无法支持spring插件,例如:AOP、Web应用等功能。
ApplicationContext
ApplicationContext是BeanFactory的子类,以一种更面向框架的工作方式以及对上下文进行分层(不同项目使用不同分模块策略),在BeanFactory基础上对功能进行扩展:
1.MessageSource, 提供国际化的消息访问
2.资源访问(如URL和文件)
3.事件传递
4.Bean的自动装配
5.各种不同应用层的Context实现
2.资源访问(如URL和文件)
ApplicationContext acxt =new ClassPathXmlApplicationContext("/applicationContext.xml");
(1)通过虚拟路径来存取。当资源位于CLASSPATH路径下时,可以采用这种方式来存取。
Resource resource = acxt.getResource(“classpath:messages_en_CN.properties”);
(2)通过绝对路径存取资源文件。
Resource resource = acxt.getResource(“file:F:/testwork/MySpring/src/messages_en_CN.properties”);
(3)相对路径读取资源文件。
Resource resource = acxt.getResource("/messages_en_CN.properties");
Resource常用的方法:
getFilename() : 获得文件名称
contentLength() : 获得文件大小
createRelative(path) : 在资源的相对地址上创建新文件
exists() : 是否存在
getFile() : 获得Java提供的File 对象
getInputStream() : 获得文件的流
二者装载bean的区别:
BeanFactory:
BeanFactory在启动的时候不会去实例化Bean,中有从容器中拿Bean的时候才会去实例化;
BeanFactory factory = new XmlBeanFactory(“XXX.xml”);
获取一个叫做mdzz的bean。在这个时候进行实例化。
factory.getBean(“mdzz”);
ApplicationContext:
ApplicationContext在启动的时候就把所有的Bean全部实例化了。
它还可以为Bean配置lazy-init=true来让Bean延迟实例化;
如何选择
延迟实例化的优点:(BeanFactory)
应用启动的时候占用资源很少;对资源要求较高的应用,比较有优势;
不延迟实例化的优点: (ApplicationContext)
-
所有的Bean在启动的时候都加载,系统运行的速度快;
-
在启动的时候所有的Bean都加载了,我们就能在系统启动的时候,尽早的发现系统中的配置问题
-
建议web应用,在启动的时候就把所有的Bean都加载了。(把费时的操作放到系统启动中完成)
Spring提供了哪些配置方式
将一个类声明为Spring的bean有哪些注解
Spring支持几种bean scope
Spring bean的生命周期
bean的生命周期是由容器控制的,主要在创建和销毁两个时期
创建:
Spring启动,查找并加载需要被Spring管理的bean,进行Bean的实例化
Bean实例化后对将Bean的引入和值注入到Bean的属性中
销毁:
bean的生命周期:
1.实例化bean对象(通过构造方法或工厂方法)
2.依赖注入,设置对象属性(setter)
3.bean实现接口,调用该接口的方法
4.将bean实例传递给bean的前置处理器
5.调用bean的初始化方法
6.将bean实例传递给bean的后置处理器
7.使用bean
8.容器关闭之前,调用bean的销毁方法
(如果bean设为prototype时,当容器关闭,destroy方法不会被调用)
什么是spring内部的bean
什么是spring bean装配
Spring中出现同名的bean怎么办
Spring怎么解决循环依赖
Spring 中单例的bean的线程安全问题
Spring AOP
AOP面向切面编程
Spring AOP是动态代理,主要有两种方式,一种是JDK动态代理,一种是CGLIB代理
JDK代理是要求被代理的类必须实现一个接口,通过反射来接收被代理的类
CGLIB代理是一个代码生成的类库,可以在运行时动态的生成某个类的子类,针对没有实现接口的情况
1.先定义一个目标类的接口
目标类的每一个方法叫joinpoint(切点),每个切点都会用到通知
2.然后实现这个接口
3.定义一个通知类,这个通知类就相当于切面
4.再写一个代理类,在代理类里面new一下目标类和切面类,然后定义切点,然后调用目标类里面方法的时候,就会发现每个方法都执行了通知,用了动态代理就不用手动的给每个方法前后加入通知,这样既节省了时间,也保证了主体代码不被改变
AOP的应用场景:
操作数据库的事务,日志,拦截器,权限控制(spring-security)等。
AOP优点:
1.通过动态代理,就可以在指定位置执行对应的流程,在指定位置插入这些功能
2.把应用业务逻辑和系统服务分开
Spring 框架用到的设计模式
Spring事务实现方式
Spring 事务定义的传播规则
Spring MVC流程
dispatcherservlet:前端控制器,接收请求,响应结果
viewresolver:视图解析器
@Controller注解
控制器类,处理由DispatcherServlet分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model返回给对应的View进行展示
@RequestMapping
@RestController和@Controller区别
@RequestMapping和@GetMapping区别
返回JSON格式使用什么注解
五.Spring的@Transactional如何实现的
步骤一、在Spring配置文件中引入命名空间
步骤二、xml配置文件中,添加事务管理器bean配置
步骤三、在使用事务的方法或者类上添加 @Transactional(“pkgouTransactionManager”)注解
六.Spring Boot
SpringBoot就是一个轻量级,简化配置和开发流程的web整合框架,主要是简化了使用Spring的难度,简省了繁重的配置,提供了各种启动器,开发者能快速上手。
优点:
简化Maven配置
缺点:
封装的太好了,出错了不容易定位
Spring Boot的核心注解是哪个?它主要由哪几个注解组成的?
@SpringBootApplication是SpringBoot的核心注解,主要组合包含了以下3个注解:
1.@SpringBootConfiguration:组合了@Configuration注解,实现配置文件的功能。
2.@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据
源自动配置功能:@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
3.@ComponentScan:Spring组件扫描
SpringBoot自动配置原理是什么?
注解@EnableAutoConfiguration,@Configuration,@ConditionalOnClass就是自动配置的核心,首先它得是一个配置文件,其次根据类路径下是否有这个类去自动配置。
如何使用Spring Boot实现异常处理?
Spring提供了一种使用ControllerAdvice处理异常的非常有用的方法。我们通过实现一个
ControlerAdvice类,来处理控制器类抛出的所有异常。
保护Spring Boot应用有哪些方法
七.Spring,Spring MVC,Spring Boot关系
Spring MVC是Spring基础上的一个MVC框架,Spring MVC配置方式直接,业务代码可以重用,但是配置文件xml,config比较繁琐,于是为了让配置不在繁琐,就引入了Spring Boot,Spring Boot也是基于Spring框架的。
Spring Spring MVC Spring Boot区别
Spring是一个开源框架,核心是IOC AOP,而SpringMVC是基于Spring功能之上添加的Web框架,想用SpringMVC必须先依赖Spring。
SpringBoot就是一个轻量级,简化配置和开发流程的web整合框架,主要是简化了使用Spring的难度,简省了繁重的配置,提供了各种启动器,开发者能快速上手。
那么SpringBoot和Spring有什么区别呢?
1.Spring Boot可以建立独立的Spring应用程序;
2.内嵌了如Tomcat,Jetty和Undertow这样的容器,也就是说可以直接跑起来,用不着再做部署工作了;
3.无需再像Spring那样搞一堆繁琐的xml文件的配置;
4.可以自动配置(核心)Spring。SpringBoot将原有的XML配置改为Java配置,将bean注入改为使用注解注入的方式(@Autowire),并将多个xml、properties配置浓缩在一个appliaction.yml配置文件中。
5.提供了一些现有的功能,如量度工具,表单数据验证以及一些外部配置这样的一些第三方功能;
6.整合常用依赖(开发库,例如spring-webmvc、jackson-json、validation-api和tomcat等),提供的POM可以简化Maven的配置。当我们引入核心依赖时,SpringBoot会自引入其他依赖。
八.MyBatis
Mybatis是一个半ORM(对象关系映射),它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要再花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。
Mybatis可以使用XML或注解来配置和映射原生信息,将POJO映射成数据库中的记录,避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。
MyBatis初始化流程
(MyBatis是一个可以自定义SQL存储过程和高级映射的持久层框架)
1.加载配置文件
2.解析配置文件、将配置文件中的信息装载到Configuration中。
3.根据Configuration创建SqlSessionFactory(会话工厂)并返回。
#和$的区别
Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 的 set 方法来赋值;
Mybatis 在处理 美刀{}时,就是把${}替换成变量的值。
使用#{}可以有效的防止 SQL 注入,提高系统安全性。
MyBatis缓存机制
一级缓存
mybatis的一级缓存是SqlSession级别的缓存,在操作数据库的时候需要先创建SqlSession会话对象,在对象中有一个HashMap用于存储缓存数据,此HashMap是当前会话对象私有的,别的SqlSession会话对象无法访问。
具体流程:
1.第一次执行select完毕会将查到的数据写入SqlSession内的HashMap中缓存起来
2.第二次执行select会从缓存中查数据,如果select相同切传参数一样,那么就能从缓存中返回数据,不用去数据库了,从而提高了效率
特点:
1.如果SqlSession执行了DML操作(insert、update、delete),并commit了,那么mybatis就会清空当前SqlSession缓存中的所有缓存数据,这样可以保证缓存中的存的数据永远和数据库中一致,避免出现脏读
2.当一个SqlSession结束后那么他里面的一级缓存也就不存在了,mybatis默认是开启一级缓存,不需要配置
3.mybatis的缓存是基于[namespace:sql语句:参数]来进行缓存的,意思就是,SqlSession的HashMap存储缓存数据时,是使用[namespace:sql:参数]作为key,查询返回的语句作为value保存的。
MyBatis利用一级缓存机制(本地缓存)防止循环引用和加速重复嵌套查询
一级缓存失效情况:(没有使用到当前一级缓存的情况,就还需要再向数据库发出查询)
1.sqlSession不同
2.当sqlSession对象相同的时候,查询的条件不同,,原因是第一次查询时候一级缓存中没有第二次查询所需要的数据
3.当sqlSession对象相同,两次查询之间进行了插入的操作
4.当sqlSession对象相同,手动清除了一级缓存中的数据
二级缓存
二级缓存是mapper级别的缓存,也就是同一个namespace的mappe.xml,当多个SqlSession使用同一个Mapper操作数据库的时候,得到的数据会缓存在同一个二级缓存区域。二级缓存默认是没有开启的。需要在setting全局参数中配置开启二级缓存
(开启二级缓存)
具体流程:
1.当一个sqlseesion执行了一次select后,在关闭此session的时候,会将查询结果缓存到二级缓存
2.当另一个sqlsession执行select时,首先会在他自己的一级缓存中找,如果没找到,就回去二级缓存中找,找到了就返回,就不用去数据库了,从而减少了数据库压力提高了性能
注意事项:
1.如果SqlSession执行了DML操作(insert、update、delete),并commit了,那么mybatis就会清空当前mapper缓存中的所有缓存数据,这样可以保证缓存中的存的数据永远和数据库中一致,避免出现脏读
2.mybatis的缓存是基于[namespace:sql语句:参数]来进行缓存的,意思就是,SqlSession的HashMap存储缓存数据时,是使用[namespace:sql:参数]作为key,查询返回的语句作为value保存的。例如:-1242243203:1146242777:winclpt.bean.userMapper.getUser:0:2147483647:select * from user where id=?:19
二级缓存与一级缓存的区别
二级缓存与一级缓存区别在于二级缓存的范围更大,多个sqlSession可以共享一个mapper中的二级缓存区域。
MyBatis是如何区分不同mapper的二级缓存区域呢?
它是按照不同mapper有不同的namespace来区分的,也就是说,如果两个mapper的namespace相同,即使是两个mapper,那么这两个mapper中执行sql查询到的数据也将存在相同的二级缓存区域中。
实现二级缓存的步骤:
1.在MyBatis 全局配置文件中开启二级缓存的配置
< setting name=“cacheEnabled” value=“true/”>
2.在对应的SQL 映射文件中加入标签。
3.实现Serializable(序列化)接口
注意:
二级缓存是一个namespace级别的缓存,如果在不同的namespace下操作同一SQL 语句,可能导致缓存中的数据不正确。在进行多表联查的时候,也可能会导致二级缓存中的数据不正确。所以在实际的开发过程中要慎用二级缓存。
Mybatis的优点
1.基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML
里,解除sql与程序代码的耦合,便于统一管理。提供xml标签,支持编写动态SQL语句,并可重用。
2.与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接。
3.很好的与各种数据库兼容(因为Mybatis使用JDBC来连接数据库,所以只要JDBC支持的数据库
MyBatis都支持)。
4.能够与Spring很好的集成。
Mybatis框架的缺点:
1.SQL语句的编写工作量较大,尤其当字段多、关联表多时,编写SQL语句的功底有一定要求。
2.SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
Mybatis与Hibernate有哪些不同?
1.Mybatis和Hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。
2.Mybatis直接编写原生态sql,可以严格控制sql执行性能,灵活度高,非常适合关系数据模型要求不高
的软件开发,因为这类软件需求变化频繁,一但需求变化要求迅速输出成功。
3.Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用hibernate
开发可以节省很多代码,提高效率。
为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?
Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。
mybatis的延迟加载
延迟加载:在真正使用数据时才发起查询,不用的时候不查询,按需加载
立即加载:不管用不用,只要一调用方法,马上发起查询
九.Spring事务,传播机制
(一)Spring事务三种声明方式
1.声明式: 使用Spring AOP配置事务,简化了代码。但是如果切入点错了,就没法准确的拦截事务了,会导致事务无法回滚
2.编程式: 手动的开启事务,手动提交,手动的抛出异常,手动回滚,优点就是都会回滚捕获到,缺点就是太麻烦了
3.注解式: 在方法或者类上直接调用@Transactional注解,方便
实现:
步骤一、在Spring配置文件中引入命名空间
步骤二、xml配置文件中,添加事务管理器bean配置
步骤三、在使用事务的方法或者类上添加 @Transactional(“pkgouTransactionManager”)注解
我用@Transactional注解的时候,发现有方法更新失败之后,没有进行回滚操作,查了一些资料后才知道,Spring事务管理不是更新失败就进行回滚,而是检测到异常才进行回滚,Spring事务默认拦截的是RuntimeException,如果说需要拦截一些方法的话,需要自己定义@Transactional,在后面加上rollbackFor=Exception.class或者是rollbackFor=Throwable.class一般选择用throwable.class,因为Throwable不仅仅包括了Execption还包括了Error
(二)Spring事务管理接口
PlatformTransactionManager: (平台)事务管理器
TransactionDefinition: 事务属性(事务隔离级别、传播行为、超时、只读、回滚规则)
TransactionStatus: 事务运行状态
1. 事务管理器:
Spring并不直接管理事务,而是提供了多种事务管理器,将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。
2.事务属性:
(1)隔离级别:读未提交,读已提交,可重复读(默认),可串行化
并发事务带来的问题:脏读,不可重复读,幻读
(2)传播行为(主要是为了解决业务层方法之间互相调用的问题)
支持当前事务的情况:
TransactionDefinition.PROPAGATION_REQUIRED: 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
TransactionDefinition.PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
TransactionDefinition.PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
不支持当前事务的情况:
TransactionDefinition.PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。
还有一种情况:
TransactionDefinition.PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
前面的六种事务传播行为是 Spring 从 EJB 中引入的,他们共享相同的概念。而 PROPAGATION_NESTED 是 Spring 所特有的。以 PROPAGATION_NESTED 启动的事务内嵌于外部事务中(如果存在外部事务的话),此时,内嵌事务并不是一个独立的事务,它依赖于外部事务的存在,只有通过外部的事务提交,才能引起内部事务的提交,嵌套的子事务不能单独提交。
(3) 事务超时属性(一个事务允许执行的最长时间)
所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。
(4) 事务只读属性(对事物资源是否执行只读操作)
(5) 回滚规则(定义事务回滚规则)
3.事务运行状态
TransactionStatus接口内容:
boolean isNewTransaction(); // 是否是新的事物
boolean hasSavepoint(); // 是否有恢复点
void setRollbackOnly(); // 设置为只回滚
boolean isRollbackOnly(); // 是否为只回滚
boolean isCompleted; // 是否已完成
十.Spring Boot注解
Controller层:
@Autowired:自动导入依赖的bean
@CrossOrigin:解决跨域问题
@Controller:接受用户请求并调用 Service 层返回数据给前端页面。
@ResponseBody:表示这个方法的返回结果直接写入HTTP response body中,在异步获取数据时使用。
@RequestMapping:处理请求地址映射的注解,主要负责URL到Controller层中的具体函数的映射。
@ExceptionHandler(Exception.class):用在方法上面,表示遇到这个异常就执行什么方法。
下单的时候总是提示下单失败,debug的时候发现session_id没有值,然后在百度上找了一些解决办法,发现是跨域的问题,然后用@CrossOrigin之后也没好使,session_id还是没传过来,最后又在@RequestMapping注解中加入了@RequestParam,最后才解决了这个跨域问题。
SessionID:
SessionID存放在服务器内存和客户的Cookie里,当用户发出请求时,服务器将用户Cookie里面记录的SessionID和服务器里存的SessionID比对
跨域问题:
跨域是a页面想要获取b页面资源,如果a,b页面的协议、域名、端口号、子域名不同,所进行的访问都是跨域的,而浏览器一般为了安全都限制了跨域访问,也就是不允许跨域访问资源。
例子:http协议,www.123.com 域名、8080 端口
解决方案:
JSONP方式,只支持GET请求,不支持POST请求。
反向代理,ngixn
www.baidu.com/index.html需要调用www.bilibili.com/server.php,可以写一个接口www.baidu.com/server.php,由这个接口在后端去调用www.bilibili.com/server.php并拿到返回值,然后再返回给index.html
配置浏览器(我配置了谷歌,属性->目标> 在后面追加 --args --disable-web-security --user-data-dir 注意有个空格)。设置成功打开浏览器是出现已栏提示证明已成功配置。
Service层:
@Service:一般用于修饰service层的组件
@Autowired:自动导入依赖的bean
@Transactional:实质是使用了 JDBC 的事务来进行事务控制的
spring接收前端请求的处理过程:(一共七种)
1.前端GET请求的URL参数与Controller类中的方法的参数名称对应
2.通过HttpServletRequest来获取前端GET请求的参数
3.通过创建一个JavaBean对象来封装表单参数或者是请求url路径中的参数
4.@RequestParam
5.@RequestBody,@RequestBody能把简单json结构参数转换成实体类
Spring Boot流程:
1.运行SpringApplication的main方法时
2.调用静态方法run(),实例化
3.SpringApplication实例化完成并且完成配置后调用run()方法,首先遍历初始化过程中加载的SpringApplicationRunListeners,然后调用starting(),开始监听springApplication的启动。
4.加载Spring Boot的配置环境
5.准备容器
6.刷新容器
十一.Spring MVC流程
具体步骤:
第一步:发起请求到前端控制器(DispatcherServlet)
第二步:前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找)
第三步:处理器映射器HandlerMapping向前端控制器返回Handler,HandlerMapping会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象,多个HandlerInterceptor拦截器对象),通过这种策略模式,很容易添加新的映射策略
第四步:前端控制器调用处理器适配器去执行Handler
第五步:处理器适配器HandlerAdapter将会根据适配的结果去执行Handler
第六步:Handler执行完成给适配器返回ModelAndView
第七步:处理器适配器向前端控制器返回ModelAndView (ModelAndView是springmvc框架的一个底层对象,包括 Model和view)
第八步:前端控制器请求视图解析器去进行视图解析 (根据逻辑视图名解析成真正的视图(jsp)),通过这种策略很容易更换其他视图技术,只需要更改视图解析器即可
第九步:视图解析器向前端控制器返回View
第十步:前端控制器进行视图渲染 (视图渲染将模型数据(在ModelAndView对象中)填充到request域)
第十一步:前端控制器向用户响应结果