Spring-IoC 基于xml管理

现大多使用注解方式,xml方式并不简洁,本文仅记录xml用作基础学习。

0、前提

首先在父项目的pom.xml中配置好依赖们。然后子模块也可以使用这些依赖。
  • 在resource目录下创建Spring的xml文件,名称无要求,本文使用bean.xml。文件最上头的几行为约束,表示可以用哪些标签等,如要使用其他标签,需先在此处添加对应的三行(xmlns:标签名=".../标签名"、xsi:schemaLocation="... ...",都把链接的末尾改为标签名)
  • 在bean.xml文件中写bean标签:id为类的唯一标识,class为类的全类名(包名+类名)
  • 根据bean.xml文件创建IoC容器

一、获取Bean:

有三种方式获取bean,基于id、基于class、基于id和class一起使用。

1. 根据id获取:getBean("id")

2. 根据类型获取:getBean(类名.class)

注意事项:
当根据类型获取bean时,要求IoC容器中指定类型的bean有且只能有一个。
当IOC容器中一共配置了多个,根据类型获取时会抛出异常。
期望匹配单实例的bean,但发现了两个,IoC不知道找谁:
只能使用其他两种方式。
扩展:

接口不能new,只能new接口的实现类。

使用实现类的类型可以获取到bean,所以此处试验接口类型能不能获取bean。

如果组件类实现了接口,根据接口类型可以获取 bean 吗?
可以,前提是bean唯一
接口UserDao,实现类UserDaoImpl。
如果一个接口有多个实现类,这些实现类都配置了 bean,根据接口类型可以获取 bean 吗?
不行,因为bean不唯一
接口UserDao,实现类UserDaoImpl、PersonDaoImpl。
原因与注意事项类似,不知道找谁。
结论:

根据类型来获取bean时,在满足bean唯一性的前提下,其实只是看:[对象 instanceof指定的类型」的返回结果,只要返回的是true就可以认定为和类型匹配,能够获取到。

java中,instanceof运算符用于判断前面的对象是否是后面的类,或其子类、实现类的实例。如果是返回true,否则返回false。也就是说:用instanceof关键字做判断时,instanceof操作符的左右操作必须有继承或实现关系

3. 根据id和类型获取:getBean("id", 类名.class)


二、依赖注入

依赖注入是指在创建对象时,给属性设置值。

原始写法:通过set方法和有参构造器赋值

有两种实现方式:Setter和构造器。

1. 基于Setter注入:<property>

  • 首先创建类,定义属性和set方法。

在类前使用lombok的@Data注解可以不用手动get、set、toString等。

  • 在bean.xml配置文件中写bean标签,使用<property>标签调用set方法赋值。

name为属性,value为具体赋值。

2. 基于构造器注入:<constructor-arg>

  • 首先创建类,定义属性和有参构造方法。
  • 在bean.xml配置文件中写bean标签,使用<constructor-arg>标签调用有参构造方法赋值。

name为属性,value为具体赋值。(name也可以用index索引但不推荐,因为顺序要一致)


3. 特殊值处理

3.1 字面量

字面量没有引申含义,就是我们看到的这个数据本身。

使用value属性给bean的属性赋值时,Spring会把value属性的值看做字面量

3.2 null-空值

不能写成如下形式,此时为name属性赋值null字符串

3.3 xml实体:转义

&lt;

3.4 CDATA节:<![CDATA[...]]>

4. 特殊类型属性注入

4.1 对象类型属性

一个类对象中有属性是另一个对象,例如在员工对象中有一个部门对象。

有三种方式:

4.1.1 引用外部bean------ref

在bean.xml中写好两个类的bean,部门bean和员工bean。

在员工bean的部门属性中用ref代替value赋值,ref="部门bean的id"

4.1.2 内部bean

在bean.xml中写员工bean,在员工bean的部门属性中声明部门bean。

4.1.3 级联属性赋值

在引用外部bean的基础上,使用对象.属性可以改变值。

4.2 数组类型属性------<array>标签

员工有多个爱好,用数组表示。

4.3 集合类型属性

4.3.1 List集合------<List>标签

一个部门有多个员工,部门对象bean中有一个员工类型的List。

因为员工是对象类型所以用ref引用外部bean,如果是字符串或其他,用value。

4.3.2 Map集合------<map><entry><key><value><ref>标签

也可以用map-key/value,一个学生有多个老师

4.3.3 引用集合类型的bean------<util:list><util:map>

由于要使用util标签,要先在bean.xml文件的最上头引入util,否则不能用:

一个学生有多门课-List,多个老师-Map,课和老师为对象类型。

两个lesson对象bean:

两个teacher对象bean:

student的bean:ref为对应util的id

4.4 p命名空间

要使用p标签,在bean.xml文件最上添加:

使用p命名空间,可以用:p:属性="值"进行赋值,而不用name、value了。

5. 引入外部属性文件

由于bean.xml文件中有很多bean,不利于修改和维护,所以把一些特定的值放在外部文件中,在引入外部文件进行注入。修改时只需修改外部文件,而不用修改配置文件。

常见的如数据库。

5.1 首先在pom.xml文件中添加数据库驱动和数据源等相关依赖。
5.2 创建外部属性文件(resource目录下),一般是.properties后缀格式,定义数据库信息,此处为jdbc.properties

=左边为名字,右边为赋值

5.3 引入外部属性文件:先在bean.xml最上头引用context名称空间,使用<context>标签引入外部属性文件,在bean中的value使用${}表达式完成注入

location为外部属性文件类路径:

class为德鲁伊连接池对象路径,value使用外部文件中的名字:

测试:


三、bean的作用域-scope

注意创建时机不同。

1. 单实例:

两个对象为同一个

2. 多实例:

两个对象不同


四、bean的生命周期

bean对象从创建到销毁的过程。

1. 生命周期过程:

bean对象创建(调用无参构造器)
给bean对象设置属性(set方法)
bean的后置处理器(初始化之前)
bean对象初始化(需在配置bean时指定初始化方法)
bean的后置处理器(初始化之后)
bean对象就绪可以使用
bean对象销毁(需在配置bean时指定销毁方法)
IOC容器关闭

2. 后置处理器:

实现BeanPostProcessor接口,并重写两个方法:postProcessBeforeInitialization和postProcessAfterInitialization。
还需在IoC容器中配置后置处理器,需要注意的是,bean后置处理器不是单独针对某一个bean生效,而是针对IoC容器中所有bean都会执行

class为接口实现类的全类名:

3. 测试

输出:


五、FactoryBean

FactoryBean是Spring的一种常用机制。帮我们把复杂组件创建的详细过程和繁琐细节都屏蔽起来。和普通的bean不同,配置一个FactorvBean类型的bean,在获取bean的时候得到的并不是class属性中配置的这个类的对象,而是getObject()方法的返回值决定创建什么对象。

将来整合Mybatis时,Spring就是通过FactoryBean机制来帮我们创建SqlSessionFactory对象的。

使用:

实现FactoryBean接口的类,重写getObject()方法,返回一个对象。

配置文件:

getBean("user")返回的user对象,而不是class的MyFactoryBean对象。

六、基于xml的自动装配

不使用自动装配即上述中的二、4.1部分使用ref。

在IoC容器匹配bean时,自动为该bean依赖的类类型、接口类型的属性赋值。

有两种方式:byName和byType

创建三个包,controller、Service、dao,其中controller包下有一个UserController类,Service包下有userService接口和实现该接口的userServiceImpl类,dao包下有userDao接口和实现该接口的userDaoImpl类。

1. 在bean.xml中的bean标签内使用autowired ="byType",在IoC容器中根据类型找bean自动装配。最好保证bean唯一。
如果没有找到匹配的类型,则该属性不匹配,默认赋值为null。如果找到多个,抛出异常NoUniqeBeanDefinitionException。
2. autowired ="byName",需保证id标识与类定义中的属性名称一致

不一致则报错,会赋空值。

参考:b站尚硅谷

相关推荐
程序猿零零漆1 分钟前
SpringCloud 系列教程:微服务的未来(二)Mybatis-Plus的条件构造器、自定义SQL、Service接口基本用法
java·spring cloud·mybatis-plus
猿来入此小猿3 分钟前
基于SpringBoot在线音乐系统平台功能实现十二
java·spring boot·后端·毕业设计·音乐系统·音乐平台·毕业源码
愤怒的代码16 分钟前
Spring Boot对访问密钥加解密——HMAC-SHA256
java·spring boot·后端
带多刺的玫瑰17 分钟前
Leecode刷题C语言之切蛋糕的最小总开销①
java·数据结构·算法
栗豆包32 分钟前
w118共享汽车管理系统
java·spring boot·后端·spring·tomcat·maven
夜半被帅醒39 分钟前
MySQL 数据库优化详解【Java数据库调优】
java·数据库·mysql
万亿少女的梦1681 小时前
基于Spring Boot的网络购物商城的设计与实现
java·spring boot·后端
醒了就刷牙1 小时前
黑马Java面试教程_P9_MySQL
java·mysql·面试
m0_748233641 小时前
SQL数组常用函数记录(Map篇)
java·数据库·sql
编程爱好者熊浪2 小时前
JAVA HTTP压缩数据
java