一文读懂SpringIoC的工作原理和机制(面试经)

前言

我们在使用Spring框架时,经常会提到IoC吧?虽然你在开发的时候,不会留太多的时间(或者没有时间)去琢磨“为什么要这样做”,但是通常会知道“这样做准没问题”。这显然没有任何问题,因为在996/007的背景下,如果谁还有时间去琢磨它怎么回事,那么可能会带来“工作不饱和”的恶果。

但是,学习归学习,工作任工作,如果能够挤一点时间,多想想“这是为什么”,我想还是事倍功倍的。正所谓“天底下,没有白费的努力,也没有一无所获的付出”。总有一天你曾经洒下的汗水,会在未来的某天以一朵惊艳之花,笑迎你的归来。

今天博主给大家讲讲Spring中的IoC吧,可以说它是Spring成功的关键技术。
在这里插入图片描述

IoC(Inversion of Control)必学必看

In software engineering, inversion of control (IoC) is a programming technique in which object coupling is bound at run time by an assembler object and is typically not known at compile time using static analysis

一句话总结:在软件工程领域,控制反转技术是对象或程序的一部分的控制被转移到容器或框架中,它常用于面向对象编程的上下文(Context)中。

那么它有哪些优点呢?且看下文:

  • 任务的实现与执行分离;
  • 在不同的实现中,自由切换;
  • 模块化程度更高;
  • 通过隔离组件或模拟其依赖关系并允许组件通过“契约”进行通信,便于测试;

说到这里,不得不提DI了,这又是什么东东?

1. DI(Dependency Injection)

Dependency Injection is a pattern through which to implement IoC, where the control being inverted is the setting of object’s dependencies.The act of connecting objects with other objects, or “injecting” objects into other objects, is done by an assembler rather than by the objects themselves.

一句话总结:依赖注入是实现IoC的一种模式,由程序而非对象本身完成。通过注入实现对象之间的绑定。

举个例子,在没有使用DI前,我们是这么处理对象之间的关系的:

// 新建一个对象,并引用另外一个对象,通过new实现
public class TextEditor{
	private SpellChecker sc;
	public TextEditor(){
		sc = new SpellChecker();
	}
}

在使用了DI后,它是这样的:

// 通过构造器注入另外一个对象
public class TextEditor{
	private SpellChecker sc;
	public TextEditor(SpellChecker spellChecker){
		this.sc = spellChecker;
	}
}

在这里,TextEditor不应该担心SpellChecker的实现。SpellChecker将独立实现并在TextEditor实例化时提供给TextEditor,该过程是由Spring Framework控制的。因此,控制流已经被依赖注入(DI)“反转”,因为您已经有效地将依赖性委托给某些外部系统。简单讲,我们直接“撒手不管”了,全权交付外部系统“一手操办”

是不是很高效?

2. IoC核心思想

org.springframework.beans和org.springframework.context包提供了对Spring框架的IoC容器的基础。其中,BeanFactory接口提供了一种能够管理任何性质的对象的高级配置机制;而ApplicationContext接口构建于BeanFactory(它是一个子接口)之上,并添加了其他功能。例如更容易与Spring的AOP功能集成,消息资源处理,事件传播和应用程序的上下文,如WebApplicationContext用于Web应用中。

org.springframework.beans.factory.BeanFactory是Spring IoC容器的表示,负责管理上述bean。配置元数据可以由XML,Java注释或Java代码表示。Spring IoC容器利用Java POJO类和配置元数据来生成完全配置和可执行的系统或应用程序。
我们可通过下图理解这一过程:
在这里插入图片描述
这个过程,就像你在组装一台车。在出厂前,需要完成轮胎的安装、发动机的安装,以及最后的集成安装等工序。

3. 创建Bean的方式

A bean definition can be seen as a recipe for creating one or more actual objects. The container looks at the recipe for a named bean when asked, and uses the configuration metadata encapsulated by that bean definition to create (or acquire) an actual object.

一句话总结:Spring容器根据需要进行对象的实例化。

3.1 构造函数

使用构造函数方法创建bean时,所有普通类都可以使用并与Spring兼容。也就是说,正在创建的类不需要实现任何特定接口或以特定方式编码。只需指定bean类就足够了。
例如:

<bean id='spellChecker' />

3.2 构造静态方法

当使用静态工厂方法定义要创建的bean以及指定包含静态工厂方法的类的class属性时,需要另一个名为factory-method的属性来指定工厂方法本身的名称。
例如:

<bean id='spellChecker' factory-method='createInstance'></bean>

3.3 构造实例工厂方法

使用实例工厂方法的实例化是调用容器中现有bean的工厂方法来创建新bean。

<bean id='myBeanFactory' class='xxx.FactoryBean'></bean>
<bean id='spellChecker' factory-bean='myBeanFactory' factory-method='createInstance'></bean>

4 依赖注入的方式

4.1 setter注入

基于Setter的DI,是通过在调用无参数构造函数或无参数静态工厂方法来实例化bean之后,再调用bean上的setter方法来实现的。

例如:

// 通过set方法DI
public class TestSetterDI{
	MyBean bean = null;
	public void setMyBean(MyBean myBean){
		this.bean=myBean;
	}
}

4.2 构造方法注入

基于构造函数的DI,是通过调用具有多个参数的构造函数来实现,每个参数代表一个协作者。

例如:

// 通过构造器DI
public class TestConstructorDI{
	MyBean bean = null;
	public TestConstructorDI(MyBean myBean){
		this.bean=myBean;
	}
}

4.3 接口注入

通过接口的实现类将依赖注入到目标对象中。

例如:

// 定义一个接口
public interface Ibusiness{
	public void create(MyBean myBean);
}
// 通过实现类完成DI
public class Business implements Ibusiness{
    MyBean bean = null;
	public void create(MyBean myBean){
		this.bean= myBean;
	}
}

结语

本文主要介绍了SpringIoc的核心原理和实现方法,相关知识是面试必答环节,好好研习一下,可助你通关哦。

走过的、路过的盆友们,点点赞,收收藏,并加以指导,以备不时之需哈~

精彩回顾

一文读懂SpringMVC的工作原理
Springboot中基于X509完成SSL检验的原理与实践
基于springboot+enum配置化实践


在这里插入图片描述

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值