文章目录
- Spring:Day 01
- 一、简介
- 1. 概述
- 2. Spring 组成
- 二、IoC 设计思想
- 三、编写一个 Spring
- 四、IoC 创建对象方式
- 五、Spring 配置
- 1. 别名
- 2. Bean 的配置
- 3. import
- 六、依赖注入
- 1. 搭建环境
- 2. Set 注入
- 3. 总结
- 补充:c 命名和 p 命名空间注入
- 七、Bean 的作用域
- 1. singleton
- 2. prototype
- 注意:
Spring:Day 01
<!-- spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.18</version>
</dependency>
一、简介
1. 概述
Spring Framework 官网:点此进入。
Spring Framework 参考文档:点此进入。
- Spring 框架即以 interface21 框架为基础,经过重新设计,并不断丰富其内涵,于 2004 年 3 月 24 日,发布了 1.0 正式版;
- Spring 框架创始人:Rod Johnson;
- 目的:解决企业应用开发的复杂性;
- 优点:
- Spring 是一个开源的免费的框架(容器);
- Spring 是一个轻量级的、非入侵式的框架;
- 两个最重要的特征:控制反转(IoC)、面向切面(AOP);
- 支持事务的处理,对框架整合的支持。
- 总结:Spring 就是一个轻量级的控制反转(IoC)和面向切面(AOP)编程的框架。
2. Spring 组成
Spring 框架是一个分层架构,由 7 个定义良好的模块组成:
- Spring Core:核心容器的主要组件是 BeanFactory,它是工厂模式的实现;
- Spring Context:是一个配置文件,向 Spring 框架提供上下文信息;
- Spring AOP:将面向切面的编程功能集成到了 Spring 框架中,为基于 Spring 的应用程序中的对象提供了事务管理服务;
- Spring DAO:面向 JDBC 的异常遵从通用的 DAO 异常层次结构;
- Spring ORM:负责框架中对象关系映射,提供相关 ORM 接入框架的关系对象管理工具;
- Spring Web:为基于 Web 的应用程序提供了上下文;
- Spring MVC:全功能的构建 Web 应用程序的 MVC 实现。
Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式。
组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现,如下图所示。
二、IoC 设计思想
IoC:Inversion of Control,控制反转,是一种设计思想。
DI:Dependency Injection,依赖注入,是一种设计模式,是实现 IoC 的一种方法。
- 传统的 Java 设计中,直接会在对象的内部通过 new 进行对象的创建,是程序主动创建出来对象;
- 对 IoC 来说,有一个专门的容器管理这些对象的生命周期,控制对象的创建,所以在 IoC 中,是通过 IoC 容器控制对象,由 IoC 容器控制外部资源的获取。
理解:没有 IoC 的程序中,我们使用面向对象编程,对象的创建以及对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制。在控制反转后,对象的创建转移给第三方,可以理解为控制反转就是获得依赖对象的方式反转了。
实现 IoC 的方式:XML 配置、注解。
注意:采用 XML 方式配置 Bean 时,Bean 的定义信息和实现是分离的。而采用注解的方式可以把两者合为一体,Bean 的定义信息直接以注解的形式定义在实现类中,从而达到零配置的目的。
总结:
- 控制反转是一种通过描述(XML 或注解)并通过第三方去生产或获取特定对象的方式;
- 在 Spring 中实现控制反转的是 IoC 容器;
- 实现 IoC 的方法的是依赖注入 DI。
三、编写一个 Spring
- 在
pom.xml
中导入依赖
<!-- spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.18</version>
</dependency>
- 编写一个实体类:
Hello.java
- 编写配置文件:
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 使用 Spring 来创建对象,在 Spring 中这些对象都成为 Bean -->
<bean id="hello" class="com.Sun3285.pojo.Hello">
<property name="str" value="Spring"/>
</bean>
</beans>
- 测试:先拿到 Spring 的容器,然后获取想要的对象
注意:
- 实体类中必须要有
set
方法,因为使用 Spring 来创建对象时使用了set
方法来注入;- 之前创建对象:
Hello hello = new Hello();
,现在使用 Spring 来创建对象,在 Spring 中这些对象都成为 Bean:
id
为变量名(对象名),相当于hello
;class
为类的全限名,相当于 new 的对象,也就是对象的实际类型;property
为对象的属性,其中name
为属性名,value
为属性对应的具体值,ref
为引用 Spring 容器中创建好的对象。- 在实体类的一侧有叶子图标,说明该实体类被 Spring 所托管;
- 在上面这个过程中,对象由 Spring 创建,对象的属性由 Spring 容器设置。对象由之前的程序本身控制反转为由 Spring 创建,变成被动地接收对象,这个过程就叫控制反转;
- 现在不需要去改动程序,要实现不同的操作,只需要在 xml 配置文件中进行修改。
四、IoC 创建对象方式
- 默认使用无参构造器创建对象,使用
property
标签,详细内容见:第六部分 Set 注入
- 如果使用有参构造器创建对象,有三种方式:
- 通过下标赋值,
constructor-arg
中所用元素有:index
和value
; - 通过参数名赋值,
constructor-arg
中所用元素有:name
和value
; - 【不建议使用】通过类型赋值,
constructor-arg
中所用元素有:type
和value
。
- 通过下标赋值,
<!-- 方式一:通过下标赋值 -->
<bean id="user" class="com.Sun3285.pojo.User">
<constructor-arg index="0" value="3"/>
<constructor-arg index="1" value="Sun1234"/>
</bean>
<!-- 方式二:通过参数名赋值 -->
<bean id="user" class="com.Sun3285.pojo.User">
<constructor-arg name="id" value="2"/>
<constructor-arg name="name" value="Sun4569"/>
</bean>
<!-- 方式三:通过类型赋值 -->
<bean id="user" class="com.Sun3285.pojo.User">
<constructor-arg type="int" value="5"/>
<constructor-arg type="java.lang.String" value="Sun3215"/>
</bean>
注意:
- 方式三中的类型
type
,如果是引用类型必须为全限名,如String
的全限名为java.lang.String
;- 不推荐用方式三,因为多个属性的类型如果相同时,不好赋值;
- 从 Spring 容器中获取
getBean
到的对象为同一个对象;- 在配置文件加载
new ClassPathXmlApplicationContext("beans.xml")
时,创建了容器中所有的对象。
五、Spring 配置
1. 别名
给对象起别名有两种方式:
- 方式一:在
bean
标签中加name
取别名,这种方式可以给同一对象取多个别名,多个别名之间用逗号、分号或空格分隔; - 方式二:用
alias
标签设置别名。
2. Bean 的配置
见上面内容
3. import
一般用于团队开发,可以将多个配置文件,导入 import
合并为一个。
如可以将多个 beans.xml
导入到一个 applicationContext.xml
中,使用时,直接使用总的配置文件即可。
<import resource="beans.xml"/>
<import resource="beans1.xml"/>
<import resource="beans2.xml"/>
注意:如果导入的多个
beans.xml
中有重名的对象,会取最后一个来创建。
六、依赖注入
依赖注入的方式有三种:
- 有参构造器注入(见第四部分);
- 【重点】Set 方式注入;
- 拓展方式注入(c 命名和 p 命名空间注入)。
接下来重点介绍 Set 方式注入。
1. 搭建环境
编写一个 Student
类,属性为复杂属性,例如包括自定义对象、数组、集合、Properties 对象等。
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbies;
private Set<String> games;
private Map<String, String> cards;
private String wife;
private Properties info;
// get/set/toString 方法等
}
// 自定义类
public class Address {
private String address;
// get/set/toString 方法等
}
2. Set 注入
注入结果
3. 总结
- 依赖注入,其实就是创建对象后,利用
set
方法给对象的属性赋值; - 在给复杂属性赋值时,灵活利用不同标签:
array
、list
、set
:这三个比较类似,都是用value
标签赋值;map
:比较特殊,用entry
标签给键和值分别赋值;props
:比较特殊,用prop
标签给键和值分别赋值,注意:和map
还不太一样;- 给属性赋空值,直接用
null
标签。
补充:c 命名和 p 命名空间注入
使用前提:需要在配置文件 beans.xml
的头文件约束中导入 c 命名和 p 命名空间:
<!-- c 命名空间 -->
xmlns:c="http://www.springframework.org/schema/c"
<!-- p 命名空间 -->
xmlns:p="http://www.springframework.org/schema/p"
- c 命名空间:对应有参构造器注入;
- p 命名空间:对应 Set 方式注入。
使用
七、Bean 的作用域
六种作用域
1. singleton
【默认】singleton:单例模式,创建的实例只有一个。实现方式:在 bean
标签中加 scope="singleton"
(也可以不加)
实现
2. prototype
prototype:原型模式,每次从容器中 get
都是一个新的对象。实现方式:在 bean
标签中加 scope="prototype"
实现
注意:
- Spring Framework 官网:https://spring.io/projects/spring-framework#overview
- Spring Framework 参考文档:https://docs.spring.io/spring-framework/docs/current/reference/html/
- Spring Framework 6.0.8 API:https://docs.spring.io/spring-framework/docs/current/javadoc-api/
- 出现以下错误,解决方法:降低依赖的版本。