文章目录
一、Spring简介
1、Spring是什么以及特性?
一句话概括:Spring是一个轻量级的 控制反转(IoC)和面向切面(AOP) 的容器(框架)。
特性:
非侵入式
:基于Spring开发的应用中的对象可以不依赖于Spring的API控制反转
:IOC——Inversion of Control,指的是将对象的创建权交给 Spring 去创建。使用 Spring 之前,对象的创建都是由我们自己在代码中new创建。而使用 Spring 之后。对象的创建都是给了 Spring 框架。依赖注入
:DI——Dependency Injection,是指依赖的对象不需要手动调用 setXX 方法去设置,而是通过配置赋值。面向切面编程
:Aspect Oriented Programming——AOP容器
:Spring 是一个容器,因为它包含并且管理应用对象的生命周期组件化
:Spring 实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。一站式
:在 IOC 和 AOP 的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上 Spring 自身也提供了表现层的 SpringMVC 和持久层的 Spring JDBC)
2、Spring的组件
Spring 的核心容器是其他模块建立的基础,由 Beans 模块、Core 核心模块、Context 上下文模块和 SpEL 表达式语言模块组成,没有这些核心容器,也不可能有 AOP、Web 等上层的功能。具体介绍如下
Beans 模块
:提供了框架的基础部分,包括控制反转和依赖注入。Core 核心模块
:封装了 Spring 框架的底层部分,包括资源访问、类型转换及一些常用工具类。Context 上下文模块
:建立在 Core 和 Beans 模块的基础之上,集成 Beans 模块功能并添加资源绑定、数据验证、国际化、Java EE 支持、容器生命周期、事件传播等。ApplicationContext 接口是上下文模块的焦点。SpEL 模块
:提供了强大的表达式语言支持,支持访问和修改属性值,方法调用,支持访问及修改数组、容器和索引器,命名变量,支持算数和逻辑运算,支持从 Spring 容器获取 Bean,它也支持列表投影、选择和一般的列表聚合等。
JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作
在 Core Container 之上是 AOP、Aspects 等模块,具体介绍如下:
AOP 模块
:提供了面向切面编程实现,提供比如日志记录、权限控制、性能统计等通用功能和业务逻辑分离的技术,并且能动态的把这些功能添加到需要的代码中,这样各司其职,降低业务逻辑和通用功能的耦合。Aspects 模块
:提供与 AspectJ 的集成,是一个功能强大且成熟的面向切面编程(AOP)框架。Instrumentation 模块
:提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用。messaging 模块
:Spring 4.0 以后新增了消息(Spring-messaging)模块,该模块提供了对消息传递体系结构和协议的支持。 jcl 模块: Spring 5.x中新增了日志框架集成的模块
Test 模块:Spring 支持 Junit 和 TestNG 测试框架,而且还额外提供了一些基于 Spring 的测试功能,比如在测试 Web 框架时,模拟 Http 请求的功能。
包含Mock Objects, TestContext Framework, Spring MVC Test, WebTestClient
二、Spring 控制反转(IOC)和依赖注入(DI)
1、概念理解
1.1、 什么是IOC
Ioc—Inversion of Control
,即“控制反转”,不是什么技术,而是一种设计思想,以前我们获取一个对象时采用的是自己创建一个的方式,这是一个主动的过程;而控制反转后,当我们需要对象时就跟工厂要,而工厂来帮我们创建或者查找对象,这是一个被动的过程。
总结:控制反转就是把创建和管理 bean 的过程转移给了第三方。而这个第三方,就是 Spring IoC Container,对于 IoC 来说,最重要的就是容器。
深入思考:
1) 谁控制谁?控制了什么?
传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建。
谁控制谁? 当然是IoC 容器控制了对象(Bean)
控制什么? 那就是主要控制了外部资源获取(不只是对象包括比如文件等)
2)为何是反转,哪些方面反转了?
有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象。
为何是反转? 因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;
哪些方面反转了? 依赖对象的获取被反转了。
3)图例解析
传统程序设计下,都是主动去创建相关对象然后再组合起来:
当有了IoC/DI的容器后,在客户端类中不再主动去创建这些对象了,如图
4)为什么要用 IoC 这种思想呢?换句话说,IoC 能给我们带来什么好处?
答:解耦!!!!
它把对象之间的依赖关系转成用配置文件来管理,由 Spring IoC Container 来管理。
如上图所示,本来 ABCD 是互相关联在一起的,当加入第三方容器的管理之后,每个对象都和第三方法的 IoC 容器关联,彼此之间不再直接联系在一起了,没有了耦合关系,全部对象都交由容器来控制,降低了这些对象的亲密度,就叫“解藕”。
1.2、什么是DI
DI:Dependency Injection,即“依赖注入”: 组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。
深入思考
1)谁依赖于谁? 为什么需要依赖?
谁依赖于谁? 当然是应用程序依赖于IoC容器
为什么需要依赖? 应用程序需要IoC容器来提供对象需要的外部资源;
2) 谁注入谁? 注入了什么?
谁注入谁? 很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;
注入了什么? 就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
1.3、 IOC和DI的关系
其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。通俗来说就是IoC是设计思想,DI是实现方式。