Sping IoC (一)

unimof 2021年03月03日 390次浏览

Spring框架中最经典的两个组件就是IOC和AOP,其中IOC(Inversion of Control)是什么呢?

1. 为什么需要 IoC

举个最简单的例子,三层架构的Web系统,Controller调用Service实现业务逻辑,Service层调用Dao层实现数据提取和持久化。

我们现在要实现一个接口:getUserList


public class UserController {
	
	public UserController (){
		serviceA = new serviceA(XX, XX, XX);
		serviceB = new serviceB(XX, XX);
		serviceC = new serviceC(XX, XX);
	}

	private ServiceA serviceA;
	private ServiceB serviceB ;
	private ServiceC serviceC;
	
	public object getUserList() {
		serviceA.xxx();
		serviceB.xxx();
		serviceC.xxx();
	}
}

在上述代码中,我们的 ServiceA,ServiceB,ServiceC 三个对象是如何实例化的呢?

一种办法,我们可以实现一个 UserController 的构造函数,new 出来:

	public UserController (){
		serviceA = new ServiceA(XX, XX, XX);
		serviceB = new ServiceB(XX, XX);
		serviceC = new ServiceC();
	}

如果 Service 不需要额外的参数,那还比较简单,直接 new 即可,例如 serviceC 。

如果需要传参数,我们还需要将所有参数对象都先 new 创建出来,然后依次传入进去,实现 Service 的创建,例如:ServiceA 和 ServiceB。

在实际的业务中,我们完全有可能不仅仅是需要创建 Dao 层的对象,还需要领域层,缓存层等等。

在复杂的情况下,手动创建对象体系就是一个灾难,导致我们的代码难易维护,层与层之间紧密耦合在一起,任何一个接口或者类的构造函数改变,都需要将所有引用的地方进行修改。。。

解决上述问题,一个很好的解决思想就是 IoC 。

2. IoC

IoC — Inversion of Control,即「控制反转 」。

IoC 思想的本质:进程内所有需要托管的类都注册到 IoC 容器,当需要创建某个类的实例时(比如:Controller 接到一个新的 Http 请求),IoC 检查该类的构造函数参数类型,并创建相应的类实例,传入到构造函数中,完成类实例的创建,这个过程是递归进行的,直到实例创建完成,或者某个需要的参数类型无法创建,终止创建过程。

还是用上面的例子来说,如果用 IoC 来进行改造,最终结果如下:

public class UserController {
	
	public UserController (ServiceA serviceA,
		ServiceB serviceB, ServiceC serviceC ){
		serviceA = serviceA;
		serviceB = serviceB;
		serviceC = serviceC;
	}

	private ServiceA serviceA;
	private ServiceB serviceB;
	private ServiceC serviceC;
	
	public object getUserList() {
		serviceA.xxx();
		serviceB.xxx();
		serviceC.xxx();
	}
}

通过比较发现,最大的不同就在于 「UserController 」的构造函数是如何实现Service 实例创建上面。

在引入 IoC 后,类的构造变得非常简洁,需要依赖什么类型,直接在构造函数中添加一个参数即可,这个过程在 IoC 当中叫做注入(当然也可以有其他方式,最常用的方式就是构造函数注入)。

  • 注入
    注入是 IoC 框架创建对象的过程,也叫依赖注入。常见的注入方式有:构造函数注入、属性注入,目前 Spring 都支持,比较推荐使用「构造函数注入」。

  • 容器
    容器是 IoC 框架用来存储类型+对象间依赖关系的部分。

传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是 松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

2. IoC 实现原理

反射——反射是IoC得以实现的核心技术。

通过前述,我们知道 IoC 思想的核心就在于类实例的创建和声明周期管理。无论 IoC 使用的是什么技术,追踪都是要创建一个类的实例,而最 根本的就是 通过反射的方式,实现实例的创建和参数的注入。