spring-第四章 spring对IOC的实现

spring


文章目录


前言

spring实现了IOC,来替我们管理java中的实例对象,这也是 spring中的重要内容之一。


1.IOC控制反转

IOC是一种编程思想,是为了降低程序耦合度,满足OCP、DIP原则。

控制反转做到以下两件事:

  • 将对象的创建权力交出去、由第三方容器负责
  • 将对象与对象之间的关系维护交出去,交给第三方容器负责

spring实现IOC的方式------依赖注入

2.依赖注入

2.1set注入方式

spring中的第一中注入方式就是set注入,该方法会调用已有的set方法为引入属性赋值。

这里我们模拟演示如何设置service层对象和dao层对象之间的依赖注入。

2.1.1提供set方法

想要让spring容器能够调用set方法,我们就需要先拥有set方法。

注意

  • set方法可以是自动生成的,也可以是我们手动创建的
  • 方法命名必须由"set"开头,后面任意
  • 记得传入与引入属性同类型的参数

2.1.2配置bean之间关系

拥有了set方法以后,我们得告诉spring容器,让它调用set方法完成注入。

介绍

  • 使用property标签配置bean之间的关系
  • name属性用来指定要使用的set方法
  • name属性值是set方法名省略"set"的那一部分,且首字母小写,如图中值为dao则说明指定的是setDao方法
  • ref属性用来指定要传给set方法的参数
  • ref属性值指定其他bean的id值,表示把对应的bean作为set方法参数

补充:要做测试的话,在获取容器时要确保传入正确的xml文件

2.2构造器注入方式

第二种依赖注入的方式就是调用构造器进行注入

需要注意的是:

  • 构造器注入方式在对象创建时进行注入,set注入方式在对象创建后进行注入(因为构造器在创建对象时执行)

这里同样以案例举例,假设有service层对象UserServiceConstructor,其中需要注入两个属性

2.2.1提供构造函数

spring要调用构造函数进行注入,我们就要提供好有参构造函数

2.2.2配置文件

  • 使用constuctor-arg标签来设置构造器的参数
  • 使用index属性来指定为第几个参数传值,从0开始计数
  • 使用ref指定传入哪一个bean作为参数,值为bean的id值
  • 可以使用name属性来代替index属性完成确定参数的工作,值是完整参数名
  • 可以省略name和index直接使用ref传值,spring会自行进行类型匹配为对应的参数赋值,不过建议还是尽量写清楚

补充:要做测试的话,在获取容器时要确保传入正确的xml文件

3.set注入详解

3.1内部bean和外部bean

3.1.1注入外部bean

注入外部bean就是在注入时选用外部的一个bean作为值进行注入,前面的所有案例都是使用这种方式。

  • 要注入的bean写在外边
  • 使用ref注入

3.1.2注入内部bean

内部bean是嵌套在另一个bean中的bean

  • 在property标签中创建bean标签

3.2注入简单类型

3.2.1什么是简单类型

我们前面都是给类对象属性进行注入操作,但有时候bean对象的属性可能是简单类型,这个时候的注入操作和前面有一些不同。

以下类型是spring中可以使用value注入的简单类型:

java基本类型及其包装类

  • 枚举
  • 字符串
  • 日期类
  • URL
  • URI
  • Class对象
  • Temporal
  • Locale

3.2.2注入简单类型

这里演示set注入方式如何注入简单类型,constructor类似

  • 使用value属性注入具体值

3.2.3简单类型注入应用举例

简单类型的注入有很多应用场景。

比如,数据库连接池使用时需要配置datasource数据源,需要我们传入数据库的driver、url、username、password。这个时候就可以把数据源对象管理成bean,然后通过简单类型注入的方式来完成配置。

补充:

数据源本身也是一个对象,其内部会封装数据库连接所需要的各种信息。

各种第三方的连接池,其数据源都实现了javax.sql.DataSource接口,所以对于各种数据源的配置都是要获取一个DataSource对象来使用。这是一个规范要求。

3.3级联属性赋值

3.3.1介绍

级联属性赋值就是在类中有另一个引用类型的属性,同时这个引用类型的属性中还有其他属性时,我们不仅为该对象赋值,还要为他的属性赋值。

3.3.2举例说明

现在有两个类Student和Clazz。

其中Clazz表示班级类,它有名称属性

Student类表示学生,有学生名称和学生所在班级两个属性

那么一个学生对象中有名字和班级属性,班级属性中又有班级名属性,如下:

我们需要为引用类型的属性,以及引用类型属性的属性赋值。

按以前我们的做法是:

  1. 单独配置studentBean以及其name属性
  2. 单独配置clazzBean以及其name属性
  3. 使用ref把clazzBean注入到studentBean中

现在我们还可以使用级联注入:

可以看出与上一种做法的差别是,我们不在clazz中对班级名称进行属性注入,而是在对studentBean中使用clazz.name对班级名称进行属性注入。

注意

要使用级联注入,需要额外提供对应属性的get方法

3.4注入数组

对象中可能有数组类型的属性,对于数组类型属性的注入,也有专有的方法,并且简单类型的数组和引用类型的数组注入方式也有差别。

3.4.1简单类型数组

有一个String[] aiHaos 属性

则注入配置如下:

  • 使用array标签,数组类型属性注入通用
  • 使用value标签,简单类型数组赋值

3.4.2引用类型数组

有一个Woman[] womens属性

则其注入配置如下:

  • 使用array标签
  • 使用ref标签

3.5注入集合

3.5.1List集合

  • 如果是非简单类型value标签换成ref标签

3.5.2Set集合

  • 如果是非简单类型value标签换成ref标签

3.5.3Map集合

  • 使用map和entry标签
  • key设置键,value设置值
  • 如果是集合中不是简单类型则key换成key-ref,value换成value-ref

3.5.4Properties

Properties是继承自HashTable的集合,所以也是一种双列集合。

  • Propertis的key和value只能是String,不能是其他类型

3.6注入特殊字符

有时我们可能想把一些特殊字符作为值进行注入,但xml文件会将这些特殊字符识别为语法关键字。

有两种解决方法:

  • 使用转义字符替换
  • CDATA区

转义字符

xml中可以使用转义字符来表示特殊符号,其对应关系如下:

如下表示注入"2<3"

CDATA区

CDATA区中的特殊符号不会被解析,可以正常使用

把注入值替换为**<!CDATA[注入内容]>**

4.基于p命名空间注入

P命名空间注入是对set注入方式一种简化用法。

4.1添加P命名空间

4.2注入

设置了p命名空间后就可以使用p:属性名直接完成注入操作。

如果是非简单类型则使用p:属性名-ref.

  • 需要先添加命名空间
  • 简单类型用p:属性名,复杂类型用p:属性名-ref
  • 本质还是使用set注入,要提供set方法

5.基于c命名空间注入

c命名空间注入是对构造器注入的一种简化。

5.1添加c命名空间

5.2注入

  • 使用c:参数序号或c:参数名来进行注入
  • 如果是非简单类型使用c:参数名或序号-ref
  • 本质是使用构造器注入,所以需要提供构造方法

6.util命名空间

util命名空间可以让我们的注入配置复用

6.1添加命名空间

同样要引入util命名空间,但是要额外配置xsd文件。

6.2使用

可以看到,把注入赋值的配置放到了util中,达到了复用的效果

7.基于xml的自动装配

spring容器可以自动完成注入操作。

可以根据名字自动装配

可以根据类型自动装配

7.1根据名字自动装配

自动装配也要依赖于set方法,所以先提供好set方法

  • 使用autowire="byName"开启名字自动装配
  • 会查找id属性匹配的bean进行注入
  • 本质会使用set进行注入,需要提供set方法
  • id是set方法名的一部分能够匹配上,比如上图会把id为orderDao的bean使用setOrderDao方法进行注入

7.2根据类型自动装配

将前面autowire属性的值设置为"byType"开启类型自动装配

  • 本质也是使用set注入,需要提供set方法
  • 如果有多个同类型的bean会注入失败

8.spring引入外部属性配置文件

我们可以把要注入的数据单独写在properties文件中,然后再从properties文件中读取到xml文件中再进行注入。

8.1引入context命名空间

  • location属性用来指定要读取的properties文件路径
  • location默认从根路径开始查找

8.2读取properties数据

properties文件中的数据格式为key=value

使用**${key}**从properties文件中读取对应的值


总结

本章介绍了spring中重要的IOC的概念。

相关推荐
计算机毕业设计小帅14 分钟前
【2026计算机毕业设计】基于Springboot的校园电动车短租平台
spring boot·后端·课程设计
调试人生的显微镜14 分钟前
Web前端开发工具实战指南 从开发到调试的完整提效方案
后端
静心观复14 分钟前
drawio画java的uml的类图时,class和interface的区别是什么
java·uml·draw.io
Java水解15 分钟前
【SQL】MySQL中空值处理COALESCE函数
后端·mysql
Laplaces Demon16 分钟前
Spring 源码学习(十四)—— HandlerMethodArgumentResolver
java·开发语言·学习
guygg8820 分钟前
Java 无锁方式实现高性能线程
java·开发语言
ss27321 分钟前
手写Spring第7弹:Spring IoC容器深度解析:XML配置的完整指南
java·前端·数据库
Python私教23 分钟前
DRF:Django REST Framework框架介绍
后端·python·django
间彧25 分钟前
Java HashMap如何合理指定初始容量
后端
用户40993225021238 分钟前
PostgreSQL全表扫描慢到崩溃?建索引+改查询+更统计信息三招能破?
后端·ai编程·trae