spring目录
1 Spring 介绍
1.1 Spring 是什么
Spring 是分层的 Java SE/EE 应⽤ full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:⾯向切⾯编程)为内核,提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应⽤技术,还能整合开源世界众多著名的第三⽅框架和类库,逐渐成为使⽤最多的 Java EE 企业应⽤开源框架。
1.2 Spring 的发展历程
Rod Johnson(spring之⽗)
2017年9⽉份发布了spring的最新版本spring 5.0通⽤版(GA)
1.3 三层架构中Spring的位置
1.4 Spring的优势
- ⽅便解耦,简化开发
通过 Spring 提供的 IoC 容器,可以将对象间的依赖关系交由 Spring 进⾏控制,避免硬编码所造成的过度程序耦合。 - AOP 编程的⽀持
通过 Spring 的 AOP 功能,⽅便进⾏⾯向切⾯的编程 - 声明式事务的⽀持
通过声明式⽅式灵活的进⾏事务的管理,提⾼开发效率和质量。 - ⽅便程序的测试
- ⽅便集成各种优秀框架
Spring 可以降低各种框架的使⽤难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz 等)的直接⽀持。 - 降低 JavaEE API 的使⽤难度
总结:可以说Spring是⼀站式框架。
1.5 Spring 的体系结构
2 IoC
2.1 程序的耦合和解耦[理解]
2.1.1 什么是程序的耦合
耦合性(Coupling),也叫耦合度,是对模块间关联程度的度量。模块间联系越多,其耦合性越强,同时表明其独⽴性越差( 降低耦合性,可以提⾼其独⽴性)。
在软件⼯程中,耦合指的就是就是对象之间的依赖性。对象之间的耦合越⾼,维护成本越⾼。因此对象的设计应使类和构件之间的耦合最⼩。
划分模块的⼀个准则就是⾼内聚低耦合。
内聚和耦合是密切相关的,同其他模块存在⾼耦合的模块意味着低内聚,⽽⾼内聚的模块意味着该模块同其他模块之间是低耦合。在进⾏软件设计时,应⼒争做到⾼内聚,低耦合。
2.1.2 ⼯⼚模式解耦
在实际开发中我们可以把三层的对象都使⽤配置⽂件配置起来,当启动服务器应⽤加载的时候,让⼀个类中的⽅法通过读取配置⽂件,把这些对象创建出来并存起来。在接下来的使⽤的时候,直接拿过来⽤就好了。
那么,这个读取配置⽂件,创建和获取三层对象的类就是⼯⼚。
2.1.3 控制反转-Inversion Of Control
上⼀⼩节解耦的思路有 2 个问题:
- 存哪去?
分析:由于我们是很多对象,肯定要找个集合来存。这时候有 Map 和 List 供选择。
到底选 Map 还是 List 就看我们有没有查找需求。有查找需求,选 Map。
所以我们的答案就是 在应⽤加载时,创建⼀个 Map,⽤于存放三层对象。
我们把这个 map 称之为容器。 - 还是没解释什么是⼯⼚?
⼯⼚就是负责给我们从容器中获取指定对象的类。这时候我们获取对象的⽅式发⽣了改变。
原来:
我们在获取对象时,都是采⽤ new 的⽅式。是主动的。
现在:
我们获取对象时,同时跟⼯⼚要,有⼯⼚为我们查找或者创建对象。是被动的。
== 这种被动接收的⽅式获取对象的思想就是控制反转,它是 spring 框架的核⼼之⼀。==
明确 ioc 的作⽤:
削减计算机程序的耦合(解除我们代码中的依赖关系)。
3 IOC 解决程序耦合
3.1.1 spring 的开发包
官⽹:http://spring.io/
下载地址:https://repo.spring.io/libs-release-local/org/springframework/spring/
解压:(Spring ⽬录结构:)
docs:API和开发规范。
libs:jar包和源码。
schema:约束。
特别说明:
spring5 版本是⽤ jdk8 编写的,所以要求我们的 jdk 版本是 8 及以上。
同时 tomcat 的版本要求 8.5 及以上。
3.2 基于 XML 的配置
3.2.1 第⼀步:添加必备的 jar 包索引到⼯程pom.xml中
<dependencies>
<!-- spring 核⼼依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
</dependencies>
3.2.2 第⼆步:在类的根路径下创建⼀个任意名称的Spring
Config xml ⽂件(不能是中⽂)
3.2.3 第三步:让 spring 管理资源,在配置⽂件中配置 service
和 dao
<!-- bean标签:⽤于配置让spring创建对象,并且存⼊ioc容器之中
id 属性:对象的唯⼀标识。
class 属性:指定要创建对象的全限定类名
-->
<!-- 配置 service -->
<bean id="accountService" class="com.zzxx.service.impl.AccountServiceImpl"/>
<!-- 配置 dao -->
<bean id="accountDao" class="com.zzxx.dao.impl.AccountDaoImpl"/>
3.2.4 测试配置是否成功
/**
* 模拟⼀个表现层
*/
public class Client {
/**
* 使⽤ main ⽅法获取容器测试执⾏
*/
public static void main(String[] args) {
// 1.使⽤ ApplicationContext 接⼝,就是在获取 spring 容器
ApplicationContext ac = new
ClassPathXmlApplicationContext("beans.xml");
// 2.根据 bean 的 id 获取对象
IAccountService aService = (IAccountService)
ac.getBean("accountService");
System.out.println(aService);
IAccountDao aDao = (IAccountDao) ac.getBean("accountDao");
System.out.println(aDao);
}
}
3.3 Spring 基于 XML 的 IOC
3.3.1 spring 中⼯⼚的类结构图
3.3.1.1 BeanFactory 和 ApplicationContext 的区别
BeanFactory 才是 Spring 容器中的顶层接⼝。
ApplicationContext 是它的⼦接⼝。
BeanFactory 和 ApplicationContext 的区别:
创建对象的时间点不⼀样。
ApplicationContext:只要⼀读取配置⽂件,默认情况下就会创建对象。
BeanFactory:什么使⽤什么时候创建对象。
3.3.1.2 ApplicationContext 接⼝的实现类
ClassPathXmlApplicationContext
它是从类的根路径下加载配置⽂件 推荐使⽤这种
FileSystemXmlApplicationContext
它是从磁盘路径上加载配置⽂件,配置⽂件可以在磁盘的任意位置。
AnnotationConfigApplicationContext
当我们使⽤注解配置容器对象时,需要使⽤此类来创建 spring 容器。
它⽤来读取注解。
3.3.2 IOC 中 bean 标签
3.3.2.1 bean 标签
作⽤
⽤于配置对象让 spring 来创建的。
默认情况下它调⽤的是类中的⽆参构造函数。
如果没有⽆参构造函数则不能创建成功。
属性
id:给对象在容器中提供⼀个唯⼀标识。⽤于获取对象。
class:指定类的全限定类名。⽤于反射创建对象。
默认情况下调⽤⽆参构造函数。
scope:指定对象的作⽤范围。
**singleton:默认值,单例的
prototype:多例的**
request:WEB项⽬中,Spring创建⼀个Bean的对象,
将对象存⼊到request域中
session:WEB项⽬中,Spring创建⼀个Bean的对象,
将对象存⼊到session域中
global session:WEB项⽬中,应⽤在Portlet环境,
如果没有Portlet环境,那么globalSession 相当于 session
init-method:指定类中的初始化⽅法名称。
destroy-method:指定类中销毁⽅法名称。
3.3.2.2 bean 的作⽤范围和⽣命周期
单例对象:scope="singleton"
⼀个应⽤只有⼀个对象的实例。它的作⽤范围就是整个应⽤。
⽣命周期:
对象出⽣:当应⽤加载,创建容器时,对象就被创建了。
对象活着:只要容器在,对象⼀直活着。
对象死亡:当应⽤卸载,销毁容器时,对象就被销毁了。
多例对象:scope="prototype"
每次访问对象时,都会重新创建对象实例。
⽣命周期:
对象出⽣:当使⽤对象时,创建新的对象实例。
对象活着:只要对象在使⽤中,就⼀直活着。
对象死亡:当对象⻓时间不⽤时,被 java 的垃圾回收器回收了。
3.3.2.3 实例化 Bean 的三种⽅式
- 第⼀种⽅式:使⽤默认⽆参构造函数
- 第⼆种⽅式:spring 管理静态⼯⼚ - 使⽤静态⼯⼚的⽅法创建对象
- 第三种⽅式:spring 管理实例⼯⼚ - 使⽤实例⼯⼚的⽅法创建对象
3.3.3 IOC依赖注⼊(DI)
3.3.3.1 依赖注⼊的概念
依赖注⼊:Dependency Injection。它是spring框架核⼼ioc的具体实现。
我们的程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。IOC 解耦只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调⽤持久层的⽅法。
那这种业务层和持久层的依赖关系,在使⽤ spring 之后,就让 spring 来维护了。
简单的说,就是坐等框架把持久层对象传⼊业务层,⽽不⽤我们⾃⼰去获取。
3.3.3.2 构造函数注⼊
顾名思义,就是使⽤类中的构造函数,给成员变量赋值。
注意,赋值的操作不是我们⾃⼰做的,⽽是通过配置的⽅式,
让 spring 框架来为我们注⼊。
具体代码如下:
3.3.3.3 set ⽅法注⼊
顾名思义,就是在类中提供需要注⼊成员的 set ⽅法。
具体代码如下:
3.3.3.4 使⽤ p 名称空间注⼊数据(本质还是调⽤ set ⽅法)
此种⽅式是通过在 xml 中导⼊ p 名称空间,使⽤ p:propertyName 来注⼊数据,
它的本质仍然是调⽤类中的 set ⽅法实现注⼊功能。
配置⽂件代码:
3.3.3.5 使⽤ Spring 表达式注⼊
此种⽅式是使⽤spring中其他对象的属性值来为当前对象实现注⼊功能,
本质仍然是调⽤类中的set ⽅法实现注⼊功能。
3.3.3.6 注⼊集合属性
顾名思义,就是给类中的集合成员传值,它⽤的也是 set ⽅法注⼊的⽅式,
只不过变量的数据类型都是集合。我们这⾥介绍注⼊数组,
List、Set、Map、Properties。
具体代码如下: