大白话说Spring:IOC控制反转和DI依赖注入

本文深入浅出地介绍了Spring的核心概念——IOC(控制反转)和DI(依赖注入)。通过历史背景和代码示例展示了传统对象创建与管理方式的弊端,解释了IOC如何解决对象耦合问题,以及DI是如何实现将对象的实例化过程交给容器来管理。通过使用@Component和@Resource注解,展示了IOC和DI如何降低类间的依赖,提高代码的灵活性。
摘要由CSDN通过智能技术生成

大白话说Spring:IOC控制反转和DI依赖注入

我们都知道,Spring两大核心思想为IOC和AOP。

而IOC的中文名是控制反转,同时我们要注意IOC是一种思想,并不是一种实现。

现在我们将通过尽可能通俗的方式去讲解IOC。

IOC诞生的历史背景

我们首先要知道,一个技术诞生,都是为了解决一个实际的生产问题。

在IOC诞生之前,我们创建对象的方式,是通过new关键词进行创建,而如果要进行对象与对象的关联,也是要在对象内部再进行new操作。

比如我们现在有一个A类和B类,如下:

class A{
	public void write(){
		B b = new B();
		b.say();
	}
}

class B{
	public void say(){
		System.out.println("Hellow,World!");
	}
}

A a = new A(); //实例化一个对象a
a.write();

结果:
Hellow,World!

如上所看到的例子,A类的write方法实现,依赖于B类,所以要在A类里面通过关键词new创建B的实力,进行方法调用。

这种方法的弊端?
(1)需要由A类去管理B类。比如A类通过new关键词创B类的实例。
(2)导致A类与B类耦合。也就意味着,代码固定了say方法只能通过B类获取,而如果B类被修改了,实现say方法的类改为C类的话,则要手动修改B为C。

引入IOC后的改变

而采用了IOC控制反转之后,上面的示例代码就可以变为如下:

@Component
public class B{
	public void say(){
		System.out.println("Hellow,World!");
	}
}

public class A{

	//通过@Resource,获取bean,然后注入到b中
	@Resource
	private B b;
	
	public void write(){
		//这里不用在通过关键词new进行创建示例b,而是可以直接调用say方法。
		b.say();
	}
}

我们查看上面的代码,并没有通过new关键字创建B的实例对象。

可能有人说,private B b这句代码不就是创建一个B的实例吗?难道不还是说明是由A控制B的实例?

这样理解就错误了,private B b只是声明一个实例b而已,并没对其进行赋值,其实就是一个空的对象。也就相当于private B b = null

而通过@Resource注解,是获取IOC容器创建的B的实例,然后赋值给A里面的b而已。

所以这里对B实例的创建就交给了IOC容器。

所以IOC解决了什么问题?

“解决了对象的过分耦合”
在这里插入图片描述

那什么又是DI依赖注入?

“DI就是IOC,只是从不同的角度说明同一个事情。”

IOC指的是控制反转,也就是把原本要开发人员通过new关键词等方式对对象进行管理,现在交给IOC容器进行管理。

DI指的是依赖注入,就是把对象之间的依赖关系的实现交给了容器。

我们再看一下上面那个例子

class A{
	public void write(){
		B b = new B();
		b.say();
	}
}

class B{
	public void say(){
		System.out.println("Hellow,World!");
	}
}

A a = new A(); //实例化一个对象a
a.write();

结果:
Hellow,World!

A的write方法实现,需要依赖于B,在传统方法中,我们直接通过New关键字实例化,然后调用b的方法。这个给A加入B的实例对象是我们自己开发人员代码实现。

而使用了DI依赖注入之后,就变成如下

@Component
public class B{
	public void say(){
		System.out.println("Hellow,World!");
	}
}

public class A{

	//通过@Resource,获取bean,然后注入到b中
	@Resource
	private B b;
	
	public void write(){
		//这里不用在通过关键词new进行创建示例b,而是可以直接调用say方法。
		b.say();
	}
}

我们可以看到,在A类中虽然声明了B的实例b,但是b只是空壳,其值为null。

而真正进行赋值操作的是IOC容器,IOC容器扫描到A类中需要获取一个B的实例,然后在程序运转的某个时刻,给A类中的private B b赋值,这之后A类中的b不再是null,而是有真实的值。

这种把实例的赋值操作交给IOC容器的方式,就是DI依赖注入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值