目录
一、IOC的基本概念和底层原理
1.1、什么是IOC?
(1)控制翻转,把对象的创建和对象之间相互调用的的过程交给Spring IOC容器来管理
(2)降低代码之间的耦合
1.1.1、Spring IOC容器
Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配好Bean之间的依赖关系,为上层应用提供准备就绪的运行环境。
Bean缓存池:HashMap实现
图1
Spring 通过一个配置文件描述 Bean 及 Bean 之间的依赖关系,利用 Java 语言的反射功能实例化 Bean 并建立 Bean 之间的依赖关系。 Spring 的 IoC 容器在完成这些底层工作的基础上,还提供了 Bean 实例缓存、生命周期管理、 Bean 实例代理、事件发布、资源装载等高级服务。
1.2、IOC底层原理
1.2.1、IOC容器
Spring 的IOC容器长什么样呢?其实Spring 作者设计了两个接口用以表示容器。分别是BeanFactory
和ApplicationContext
。
- BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身是整个IOC最底层的接口。也是ApplicationContext接口继承的源头;
- ApplicationContext 面向使用Spring框架的开发者几乎所有的应用场合我们都直接使
ApplicationContext
而非底层的BeanFactory
。
1.2.2、IOC容器装配Bean的方式
IOC有两种装配Bean的方式: 依赖查找(DL)和 依赖注入(DI)。
- 依赖注入(DI)是Spring 最主要的使用方式。主要使用两种方式
setter()方法注入
和构造函数注入
。 - 依赖查找(DL)Spring也支持但是不推荐使用(主要是博主也不会) ,因为他需要用户自己去是使用 API 进行查找资源和组装对象。具有侵入性
1.2.3、IOC容器装配Bean的操作
SpringIOC容器装配Bean有4种方式:
- XML配置
- 注解
- JavaConfig
- 基于Groovy DSL配置(工作中很少使用)
总的来说:Spring在日常工作中主要使用XML和注解,其中注解这种方式占大头!
1.2.3.1、基于XML
假设有类User.java
package com.User;
/**
* @description:
* @author: 陈声铭
* @time: 2022/9/18 16:21
*/
public class User {
private String name;
public User(String name) {
System.out.println("有参构造");
this.name = name;
}
public User() {
System.out.println("无参构造");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("Set函数");
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
假设有配置文件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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--无参构造创对象
类型 变量名 = new 类型();
Hello hello =new Hello();
id = 变量名
class = new 的对象
property相当于给对象中的属性设值!
-->
<bean id="user" class="com.User.User">
<property name="name" value="陈声铭"/>
</bean>
</beans>
我们就可以借助Xml装配Bean
import com.User.User;
import com.util.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @description:
* @author: 陈声铭
* @time: 2022/9/18 16:27
*/
public class MyTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/beans.xml");
System.out.println(applicationContext.getBean("user"));
}
}
可以看到
- User对象的创建是通过
构造函数注入
- Name属性的添加是通过
setter()方法注入
这就是Spring-IOC通过依赖注入(DI)装配Bean的方式
1.2.3.2、基于注解
注解分两类装配注解和注入注解
装配注解:@Component 、@Service、@Controller、@Repository
注入注解:@Autowired(根据类型注入)、@Qualifier(根据id注入)
1.2.4、IOC容器装配Bean的作用域
IOC容器装配Bean的作用域
- 默认是singleton,即单例模式,是Spring装配Bean默认的模式。容器在启动时,自动实例化所有singleton的Bean并缓存与容器中。这样做有一个好处,当程序运行时使用到bean时从直接缓存中读取,提高了运行效率。
装配流程参考 图1
- prototype,Spring容器启动时不会实例化prototype的bean。每次从容器调用bean时都会创建一个新的对象。
- request,每次http请求都会创建一个对象(工作中极少使用)
- session,同一个session共享一个对象(工作中极少使用)
- global-session(工作中极少使用)