IOC 容器
(1) IOC 底层原理。
(2) IOC 接口(BeanFactory)。
(3) IOC 操作 Bean 管理(基于 xml)。
(4) IOC 操作 Bean 管理(基于注释)。
什么是 IOC
百度解释 – 链接
(1) 控制反转,把对象创建和对象之间的调用过程,交给 Spring 进行管理。
(2) 使用 IOC 目的:为了耦合度降低。
(3) 入门案例解释 IOC 的实现。
IOC 底层原理
(1) xml 解析、工厂模式(设计模式)、反射。
IOC (接口)
- IOC 思想基于 IOC 容器完成,IOC 容器底层就是对象工厂
- Spring 提供 IOC 容器实现两种方式:(两个接口)
(1) BeanFactory
(2) ApplicationContext
这两个接口功能类似,都可以通过加载配置文件,通过工厂获取对象。
我们将之前的代码改成 BeanFactory 也可以正常执行
// ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
BeanFactory context = new ClassPathXmlApplicationContext("bean1.xml");
但是他们肯定是有区别的。
(1) BeanFactory : IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用。
- 加载配置文件的时候不会创建对象,在获取对象(使用)才取创建对象。
(2) ApplicationContext : BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人员进行使用。
- 加载配置文件时候就会把在配置文件对象进行创建
ApplicationContext 接口实现类
主要的实现类是两个:
- FileSystemXmlApplicationContext
读取任意位置,比如 C盘下的某个 xml 文件。
如果写了盘符的路径,就是绝对路径。否则就是项目为根目录。 - ClassPathXmlApplicationContext
读取 src 目录下的 xml 文件。
IOC 操作 Bean 管理
1、什么是 Bean 管理
- Bean 管理指的是两个操作。
- Spring 创建对象。
- Spring 注入属性。
2、Bean 管理操作有两种方式
(1) 基于 xml 配置文件方式实现。
(2) 基于注解方式实现。
基于 xml 配置文件方式
1 . 基于 xml 方式创建对象
<!-- bean1.xml -->
<!-- 配置 User 对象创建 -->
<bean id="user" class="com.tt.stu.spring5.User"></bean>
(1) 在 spring 配置文件中,使用 bean 标签,标签里面添加对应的属性,就可以实现对象创建。
(2) 在 bean 标签有很多属性。
- id 属性:唯一标识,通过这个唯一标识得到对象。
- class 属性:类的全路径(包和类路径)
- name 属性:作用和 id 一样,id 不能加特殊符号,name 可以加特殊符号,基本上不使用了。
(3) 创建对象的时候,默认也是执行无参构造方法完成对象创建。
2 . 基于 xml 方式注入属性
(1) DI:依赖注入,就是注入属性
第一种注入方式:使用 setter 方法进行注入。
a. 创建类,定义属性和对应的 setter 方法
public class Book {
// 创建属性
private String bookName;
private String bookAuthor;
// 创建属性对应的 set 方法
public void setBookName(String bookName) {
this.bookName = bookName;
}
public void setBookAuthor(String bookAuthor) {
this.bookAuthor = bookAuthor;
}
@Override
public String toString() {
return "Book{" +
"bookName='" + bookName + '\'' +
", bookAuthor='" + bookAuthor + '\'' +
'}';
}
}
b. 在 spring 配置文件配置对象创建,配置属性注入
<!-- set 方法注入属性 -->
<bean id="book" class="com.tt.stu.spring5.Book">
<!-- 使用 property 完成属性注入
name: 类里面的属性名称
value: 向属性注入的值
-->
<property name="bookName" value="Java"></property>
<property name="bookAuthor" value="author"></property>
</bean>
c. 使用
@Test
public void testBook1() {
// 通过 xml 得到 class 路径
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
// 通过反射得到对象
Book book = context.getBean("book", Book.class);
// 使用对象
System.out.println(book);
}
控制台打印结果:
Book{bookName='Java', bookAuthor='author'}
可以看出来成功完成了注入属性
第二种注入方式:使用有参数的构造进行注入
a. 创建一个构造器有参数的类
public class Orders {
private String orderName;
private String address;
// 有参数构造
public Orders(String orderName, String address) {
this.orderName = orderName;
this.address = address;
}
@Override
public String toString() {
return "Orders{" +
"orderName='" + orderName + '\'' +
", address='" + address + '\'' +
'}';
}
}
b. 在 spring 配置文件中进行配置
<!--bean1.xml -- 有参数构造注入属性-->
<bean id="orders" class="com.tt.stu.spring5.Orders">
<constructor-arg name="orderName" value="abc"></constructor-arg>
<constructor-arg name="address" value="China"></constructor-arg>
</bean>
c. 使用
@Test
public void testOrders() {
// 1. 加载 spring 配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
// 2. 获取配置创建的对象
Orders orders = context.getBean("orders", Orders.class);
System.out.println(orders);
}
控制台打印结果:
Orders{orderName='abc', address='China'}
成功完成了注入属性
另外我们在使用 constructor-arg 时还可以使用 index 属性进行注入属性。index 表示第几个参数
<!-- 表示第0个参数注入 abc 的值 -->
<constructor-arg index="0" value="abc"></constructor-arg>