深入理解Spring核心技术05---Spring中的依赖注入

16 篇文章 1 订阅
9 篇文章 0 订阅

         在前面的几篇博客中给大家介绍了Spring中的IOC容器,现在大家应该都知道IOC容器的概念和实现的原理了吧,IOC容器是Spring的核心,他的功能就是帮助开发者去存储对象以及管理对象之间的关系。不用让开发者自己去管理对象之间的关系,使开发者只需要专注于业务逻辑。前面的一篇博客中给大家手动实现了一个IOC容器,通过反射加载配置文件创建并把对象存储在一个Map集合中,这里的Map集合就是一个IOC容器。好了,既然已经知道了那么Spring中是怎么创建并存储对象的原理。那么今天就来聊一聊Spring中是如何处理对象之间的关系。

          首先大家应该知道什么是对象之间的关系吧,对象与对象之间的关系用专业的术语叫做依赖,故名思意,也就是说当一个对象在实现某个功能的时候需要使用另外一个对象的属性或者方法的时候,我们就说这两个对象之间具有依赖关系。

         好了,大家可能会好奇,假设在Spring容器中有两个对象A和B,对象A在实现他的功能的时候需要使用对象B的一个属性,那么我们就称之为对象A依赖与对象B。大家首先可能会想到装饰者模式。将B对象的属性直接通过构造直接传入即可。那么在Spring中我们该怎么在配置文件中配置Bean呢?

         其实在Spring中我们并不需要去关注这个问题,前面说了Spring容器会帮我们管理对象之间的关系,所以我们直接用A对象就可以了,不用去处理A对象和B对象之间的关系。原因就是在Spring创建A对象的时候就会自动的把A对象所依赖的B对象注入到B对象中,而这个过程就是我们今天要聊的话题------DI(Dependency Injection)即依赖注入。

         概念性的东西解释的差不多了,下面来通过一个案例来解释一下把,打开eclipse,创建一个工程,包结构如下图所示:

接着我们先来创建 dao层的 接口,代码如下:

public interface DIDemo {
	public void diDemo();
}

接着创建该接口的实现类,代码如下:

public class DIDemoImpl implements DIDemo {

	@Override
	public void diDemo() {
		// TODO Auto-generated method stub
		System.out.println("Spring 中的 Dao");
	}

}

为了方便演示效果,这里我们只些简单的一条打印语句。好了,dao层的工作做完了之后我们就来开始编写service层的代码了。

先来定义service层的接口代码如下:


public interface DIDemoService {
	public void diDemoService();
}

同样的接口中只有一个方法,接下俩看看该接口的实现类把,代码如下:

import di.dao.DIDemo;

public class DIDemoServiceImpl implements DIDemoService {
	
	//声明一个dao的对象
	private DIDemo dao;
	//添加该对象的set方法,用于依赖注入
	

	public void setDao(DIDemo dao) {
		this.dao = dao;
	}


	@Override
	public void diDemoService() {
		this.dao.diDemo();
		// TODO Auto-generated method stub
		System.out.println("Spring 中的 Service ");
	}

}

大家可以看到,在上面的一段代码中我特意的让dao层的对象和service层产生依赖关系。该类种是通过set方法将dao对象注入到service层的对象中。好了到了这里我们就来编写配置文件了。

bean.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">
	
	<!-- dao -->
	<bean id="dao" class="di.dao.DIDemoImpl"></bean>
	<!-- service -->
	<bean id="DIService" class="di.service.DIDemoServiceImpl">
		<!-- 注入dao对象 -->
		<property name="dao" ref="dao"/>
	</bean>
	
	</beans>

大家可以看到,在service的配置中有一段使用了<property>,该标签的功能就是在id标识的对象中注入其他对象,我们可以看到该标签中有两个属性值,一个是name,另外一个是name对应的值。name对应的值有两种情况,一个是value,一个是ref。value对应的是给属性赋值是基本数据类型和string类型的。ref是对应的当前xml文件中配置过的bean类型。本例中由于 dao是在上一行配置过,所以选择ref。

好了,配置的工作已经做完了,下面就来编写测试类了。测试类的代码如下 :

public class Client {
	@Test
	public void  diTest() {
		
		((DIDemoService)(new ClassPathXmlApplicationContext("bean.xml")
				.getBean("DIService"))).diDemoService();
	}
}

好了,上面的就是测试类的代码了,大家可以看到这个类中只有一句代码。大家先来看看结果,稍后再给大家解释。

大家可以看到,测试的结果是同时打印出了dao对象中的一句话,这段代码可能不好理解,大家可以看到getBean方法中传入的是Service层的对象,但是打印出来了dao层的对象中的一句话,这就是spring中的依赖注入。这段代码可能大家看不懂,大家再来看下面只能这段代码,或许就豁然开朗了。

@Test
	public void  diTest() {
		ApplicationContext application = new ClassPathXmlApplicationContext("bean.xml");
		DIDemoService service = (DIDemoService)application.getBean("DIService");
		service.diDemoService();
	}
	

大家可以看到,上述方法中有三行代码,第一行使用来加载配置文件的,第二行是用来获取我们需要用的service层的对象的,第三行是执行service对象的方法。这个相信大家都能看明白。那么为什么我会先给大家看上面的那种写法呢?这里我主要是想给大家介绍一下内存相关的知识点。大家都知道,当new出现的时候就会在堆内存上分配一块空间,用来存放new出来的对象,每个new出来的对象都会有一个地址,该地址用一个16进制的数来标识,而对象的引用就比如application的值就是对象的地址,这个时候我们称之为application这个引用指向了new ClassPathXmlApplicationContext("bean.xml");这个对象。由于本案例中主要就是演示效果,所以写成一句代码不用去声明两个对象的引用,这个时候就可以节省两块栈内存的空间。和实际对象不同,对象的引用application是存放在栈内存中的。这个还真有点不好解释,反正大家只需要知道,在开发的过程中如果考虑性能的话究竟可能的减少栈内存的使用。关于内存的问题后面会专门给大家介绍。

好了,今天主要给大家演示了一下spring中的依赖注入,本案例中使用的是set方法注入,其实在Spring 中不光有这一种注入的方式,也有通过构造方法的方式注入,原理是使用带参数的构造方法注入依赖的对象,类似于装饰者模式。

需要注意的是Spring中不支持接口的注入方式。好了,今天就和给大家介绍到这里了,希望大家都能有自己的收获。下一篇博客中讲给大家详细的讲解Spring中的AOP。

 

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值