1、面向对象
2、Spring的IOC
什么是IOC?
IOC是
Inversion of Control
的缩写,多数书籍翻译成
“
控制反转
”
。
1996年,
Michael Mattson
在一篇有关探讨面向对象框架的文章中,首先提出了
IOC
这个概念。对于面向对象设计及编程的基本思想,前面我们已经讲了很多了,不再赘述,简单来说就是把复杂系统分解成相互合作的对象,这些对象类通过封装以后,内部实现对外部是透明的,从而降低了解决问题的复杂度,而且可以灵活地被重用和扩展。
IOC理论提出的观点大体是这样的:借助于
“
第三方
”
实现具有依赖关系的对象之间的解耦。
如下图:
图 IOC解耦过程
大家看到了吧,由于引进了中间位置的“
第三方
”
,也就是
IOC
容器,使得
A
、
B
、
C
、
D
这
4
个对象没有了耦合关系,齿轮之间的传动全部依靠“
第三方
”
了,全部对象的控制权全部上缴给
“
第三方
”IOC
容器,所以,IOC容器成了整个系统的关键核心,它起到了一种类似
“
粘合剂
”
的作用,把系统中的有对象粘合在一起发挥作用,如果没有这个“
粘合剂
”
,对象与对象之间会彼此失去联系,这就是有人把
IOC
容器比喻成
“
粘合剂”
的由来。
我们再来做个试验:把上图中间的
IOC
容器拿掉,然后再来看看这套系统:
图 拿掉
IOC
容器后的系统
我们现在看到的画面,就是我们要实现整个系统所需要完成的全部内容。这时候,A
、
B
、
C
、
D
这
4
个对 象之间已经没有了耦合关系,彼此毫无联系,这样的话,当你在实现A
的时候,根本无须再去考虑
B
、
C和D
了,对象之间的依赖关系已经降低到了最低程度。所以,如果真能实现
IOC
容器,对于系统开发而言,这将是一件多么美好的事情,参与开发的每一成员只要实现自己的类就可以了,跟别人没有任何关系!
我们再来看看,控制反转(IOC)
到底为什么要起这么个名字?我们来对比一下:
软件系统在没有引入
IOC
容器之前,如图
1
所示,对象
A
依赖于对象
B
,那么对象
A
在初始化或者运行到某一点的时候,自己必须主动去创建对象B
或者使用已经创建的对象
B
。无论是创建还是使用对象
B
,控制权都在自己手上。
软件系统在引入IOC
容器之后,这种情形就完全改变了,如图
3
所示,由于
IOC
容器的加入,对象
A
与对象B之间失去了直接联系,所以,当对象
A
运行到需要对象
B
的时候,
IOC
容器会主动创建一个对象
B
注入到对象A
需要的地方。
通过前后的对比,我们不难看出来:对象A
获得依赖对象
B
的过程
,
由主动行为变为了被动行为,控制权颠倒过来了,这就是“
控制反转
”
这个名称的由来。
3、Spring的DI
4、Spring的AOP
什么是AOP?
AOP(
Aspect-Oriented Programming
,面向方面编程),可以说是
OOP
(
Object-Oriented
Programing,面向对象编程)的补充和完善。
OOP
引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP
则显得无能为力。也就是说,OOP
允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting
)代码,在
OOP
设计中,它导致了大量代码的重复,而不利于各个模块的重用。
而AOP技术则恰恰相反,它利用一种称为
“
横切
”
的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”
,即方面。所谓
“
方面
”
,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP
代表的是一个横向的关系,如果说
“
对象
”
是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“
方面
”
了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。
使用“横切
”
技术,
AOP
把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop
的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade
公司的高级方案构架师
Adam Magee
所说,AOP的核心思想就是
“
将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。
”
5、SpringBoot
6、SpringMVC
Spring MVC运行流程图:
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.
将渲染结果返回给客户端。