Spring学习笔记(1.2):什么是依赖查找,依赖查找的实现方式

本文是我学习的一个总结


#a这片文章是对自己学习的总结。


1、什么是依赖注入

简单回忆一下控制反转的概念(IOC)。

开发过程中,我们在一个类中的代码常常会依赖到其他的类对象。比如下面的service类需要用到dao类提供的操作数据库的方法,也就是service依赖dao。没有dao,service的一些方法就没法进行下去。

既然需要这个类对象,那最简单的方式就是直接去new出来。

public class ServiceImpl implements Service {
	public void insertData(String data) {
		//直接new
		Dao dao = new Dao();
		dao.insert(data);
	}
}

这里ServiceImpl和Dao产生了依赖关系,ServiceImpl依赖Dao。这种情况下,ServiceImpl需要Dao的时候,ServiceImpl是主动去创建一个dao对象(注意是主动创造)。

这种主动创建的行为会带来一些麻烦。因为代码已经写死了,A和B是直接耦合在一起的。如果以后因为业务需求,类B的创建出现了一些问题,比如无法直接new,构造器被隐藏设为私有。等业务人员改完B的代码,重新启动项目后发现A开始报错,又不得不去处理A的逻辑。看到了吧,我们只是想修改B的逻辑,但因为一些依赖关系又不得不去处理很多”原本不应该管的逻辑“。可以想象。这样的依赖关系如果多了的话,那后期维护代码会变得举步维艰。

仔细想想,A和B的依赖中,A只是想要B的服务。A其实不需要关系B的创建过程,只要有个B的对象来提供服务就好。

正是有了这个突破点,控制反转的概念顺势而出,即当类A与类B产生依赖关系时(A需要B),不需要A去主动创建B,而是交给外界创建好B对象,然后通过一些方式把B对象交给A使用。

控制反转的意思是将创建B这个行为的主动权从需要方类A的手中反转到其他人手中。

只是外界创建好依赖对象B后,A可以通过多种方式获取到B。其中,A通过容器主动查找的方法,被称为依赖查找。


2、依赖查找的实现方式

依赖查找有两种实现方式,依赖拖曳和上下文查找。在介绍这两种实现方式之前,要记住依赖查找是当A依赖到B时,A主动向容器中查找B对象(getBean()方法)。依赖拖曳和上下文查找都是这样获取依赖的。两者的不同之处在于如何选择和获取到容器。

2.1 依赖拖曳(Dependency Pull)

依赖拖曳获取容器的方法是在代码中写死的。其逻辑是从配置文件(.properties,xml文件等)中生成容器,然后再从容器中查找需要的依赖对象。也就是说,依赖对象必须在指定的配置文件中配置好。

我们来改造文章开头的例子,从代码中看看依赖拖曳如何获取依赖的。

public class ServiceImpl implements Service {
	public void insertData(String data) {
		//注意getFactory方法,依赖拖曳和上下文查找只有getFactory的实现不同而已
		BeanFactory beanFactory = getFactory();
		//得到容器后直接getBean方法查找依赖对象
		Dao dao = (Dao) beanFactory.getBean("dao");
		dao.insert(data);
	}
	
	private BeanFactory getBeanFactory() {
		//从指定配置文件中获取容器
		XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
		return beanFactory;
	}
}

2.2 上下文查找

顾名思义,上下文查找的查找方式是和当前环境有关的。与依赖拖曳那样永远通过指定容器的方式不同,上下文查找获取容器的方式是动态的,是由外界传来的。

我们还是以代码为例。

public class ServiceImpl implements Service {
	//在方法中传入beanFactory,这就不是从指定配置文件中获取beanFactory了。
	public void insertData(String data, BeanFactroy beanFactory) {
		Dao dao = (Dao) beanFactory.getBean("dao");
		dao.insert(data);
	}
}

从代码中可以看出,beanFactory是由外界传来的。那这个beanFactory的来源就不是固定的了,这一点和依赖拖曳不同。


3、依赖注入(DI)和依赖查找(DL)的比较

关于依赖注入的介绍可以看这篇文章

两者都是符合IoC的一个原则,(A的逻辑中需要B的服务,A依赖B。A是依赖对象,B是被依赖对象)即被依赖对象不再由依赖对象主动创建,创建管理被依赖对象的工作交给容器,依赖对象只管用就行了。

DI和DL相比较,很明显DI的处理方式更符合IoC的思想。毕竟IoC理念提出来就是为了解决耦合问题,让开发人员更专注于业务代码而不用考虑与业务无关的依赖等问题。

从依赖查找的的实现方式中我们可以看到,依赖查找对业务代码是有侵入性的。业务代码中必须包含着获取beanFactory的容器的逻辑,而获取beanFactory明显不属于业务逻辑。

依赖查找唯一比依赖注入好的地方,就是代码的逻辑比较明显。我们能从代码中很明显地看到被依赖对象是从容器中来的,而如何获取到容器也是显而易见的。但依赖查找就没那么明显,被依赖对象的注入方式写得比较隐晦。

猜你喜欢

转载自blog.csdn.net/sinat_38393872/article/details/106610663