在分析原理之前我们先回顾下依赖注入的概念:

我们常提起的依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。具体含义是:当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者 实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。

其实简单的说,依赖注入起到的作用就是讲对象之间的依赖关系从原先的代码中解耦出来,通过配置文件或注解等方式加上Spring框架的处理让我们对依赖关系灵活集中的进行管理。  

下面谈谈Spring是如何实现反转模式IOC或依赖注入模式DI:

平时,我们需要生成一个对象,使用new语法,如一个类为A

public class A{
public void myMethod(){
System.out.println("hello");
}
}

如果我们在 B中调用A,那么如下代码:

public class B{
public void invoke(){
A a = new A();
a.myMethod();
}
}

每次执行invoke方法时,都要生成一个A对象,如果A对象代码较长,这是费时的事
情。于是有如下写法:

public class B{
A a = new A();
public void invoke(){
a.myMethod();
}
}

将A对象变成B的类属性。 如果我们不想在B中实现A的实例,也就是不想立即new A(),而是想通过外界传入, 注意,如果你想知道为什么,这里涉及到设计模式以及解耦等因素,进一步感兴趣者可学习 本站的GoF 23 种设计模式。

如果想让A的实例从外界传入,有两种写法:

public class B{
A a;
public void setA(A a){
this.a = a;
}
public A getA(){
return a;
}
public void invoke(){
a.myMethod();
}
}

这种写法,A并没有被实例化,需要通过外界调用setA方法,将A的对象实例赋入B中. 或者通过B的构造函数传入,如下:

public class B{
A a;
public B(A a){
this.a = a;
}
public void invoke(){
a.myMethod();
}
}

上述两种写法在编程中是经常发生的,B作为调用者,A是被调用者,A的实例化不在 调用者B内部中完成,而是通过构造函数或setXXX方法赋值进来,这种方式我们称为依赖 性注射(IoC 模式),B 和A 的依赖联系是通过构造函数或setXXX 方法赋值进来,这样, 最大程度解耦了调用者B和被调用者A之间的耦合联系。

Spring如何实现依赖注射?

上文提到:A的实例化不在调用者B内部中完成,而是通过构造函数或setXXX 方法赋 值进来,Spring实际就是完成这个赋值的过程。 为了让Spring自动完成B代码中的A的实例化,需要通过配置文件告诉Spring有关A 的类的属性,这个配置是applicationContext.xml文件。 在 applicationContext.xml中,我们先定义JavaBeans为B的配置:

<beans>
<bean id="b" class="springsimple.B"/>
</beans>

这是最常用的JavaBeans的定义,id相当于对象名,当前文件应该是唯一。后来Spring使用@Component替代。

再在applicationContext.xml定义A的配置如下:

<beans>
<bean id="b" class="springsimple.B"/>
<bean id="a" class="springsimple.A"/>
</beans>

这样我们告诉Spring我们有两个JavaBeans,现在解决关键问题,B代码中还调用了A, 那么如何让Spring将A的实例注射到B中?使用Spring配置的property语法。具体配置如 下:

<beans>
<bean id="b" class="springsimple.B">
<property name="a"><ref local="a" /></property> <!— 增加这一行-->
</bean>
<bean id="a" class="springsimple.A" />
</beans>

增加一行说明:B 的属性a 指向了a,这样,Spring 会知道B 中属性a 的实例就是 springsimple.A,在B实例化时将会将B中的a 实现实例化,这是通过setA方法注射进入。 注意,property name="a"中的a 是setA字符中去掉set 后的字符串,这个字符串第一个 必须是小写,例如,如果B中有setOneA方法,那么,配置文件应该是property name="oneA"。

在Spring Boot以后版本已经可以使用@Autowire进行自动匹配,无需如此繁琐配置了。

参考:

Spring依赖注入原理分析的更多相关文章

  1. Spring学习笔记——Spring依赖注入原理分析

    我们知道Spring的依赖注入有四种方式,各自是get/set方法注入.构造器注入.静态工厂方法注入.实例工厂方法注入 以下我们先分析下这几种注入方式 1.get/set方法注入 public cla ...

  2. Spring 依赖注入原理

    所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中.当spring容器启动后,spring容器初始化,创建并管理bean对象,以及销毁它.所以我们只需从容器直接获取Bean对象就行, ...

  3. Spring依赖注入原理

    接触过spring 的同学应该都知道依赖注入,依赖注入又称控制反转,其内涵就是,将创建某个bean的控制权力,由原来需要引用这个bean的bean转移(反转)到外部的spring IOC容器,由IOC ...

  4. 形象化的spring 依赖注入原理

      转. IoC就是Inversion of Control,控制反转.在Java开发中,IoC意味着将你设计好的类交给系统去控制,而不是在你的类内部控制.这称为控制反转. 下面我们以几个例子来说明什 ...

  5. spring依赖注入原理剖析

    PropertyDefinition.java package junit.test; public class PropertyDefinition { private String name; p ...

  6. Spring 依赖注入优化

    Spring 依赖注入优化 原创: carl.zhao SpringForAll社区 今天 Spring 最大的好处就是依赖注入,关于什么是依赖注入,在Stack Overflow上面有一个问题,如何 ...

  7. Spring 源码分析之 bean 依赖注入原理(注入属性)

         最近在研究Spring bean 生命周期相关知识点以及源码,所以打算写一篇 Spring bean生命周期相关的文章,但是整理过程中发现涉及的点太多而且又很复杂,很难在一篇文章中把Spri ...

  8. Spring、Spring依赖注入与编码剖析Spring依赖注入的原理

    Spring依赖注入 新建PersonIDao 和PersonDao底实现Save方法: public interface PersonIDao { public void save(); } pub ...

  9. (转)编码剖析Spring依赖注入的原理

    http://blog.csdn.net/yerenyuan_pku/article/details/52834561 Spring的依赖注入 前面我们就已经讲过所谓依赖注入就是指:在运行期,由外部容 ...

随机推荐

  1. php数组转xml

    0x00 需求 最近要做百度.360.神马搜索的网站sitemap,三家的格式都是xml,然而具体的细节还有有差别的. 一开始用的是dom,没有使用sax,写了几段便觉得太傻了,想到有没有数组转xml ...

  2. [转]我的MYSQL学习心得(六) 函数

    这一节主要介绍MYSQL里的函数,MYSQL里的函数很多,我这里主要介绍MYSQL里有而SQLSERVER没有的函数 数学函数 1.求余函数MOD(X,Y) MOD(X,Y)返回x被y除后的余数,MO ...

  3. org.apache.hadoop.hbase.MasterNotRunningException解决策略

    执行HBase时常会遇到个错误,我就有这种经历. ERROR: org.apache.hadoop.hbase.MasterNotRunningException: Retried 7 times 检 ...

  4. android App抓包工具的应用(转)

    安装好 fiddler ,手头有一部Android 手机,同时 还要有无线网,手机和 电脑在同一个无线网络.这些条件具备,我们就可以 开始下面的步骤了. 正题 :Fiddler 主菜单 Tools - ...

  5. 高并发TCP连接数目问题

    linux可通过五元组唯一确定一个链接:源IP,源端口,目的IP,目的端口,传输层协议.而一个端口不允许被两个及以上进程占用(一个进程可同时占用多个端口),据此是否可以推测一台linux服务器最多可以 ...

  6. sqoop 从sqlserver2008 导入数据到hadoop

    今天终于开始上手导入数据到hadoop了,哈哈,过程蛮崎岖的,和官方文档的还不太一样. OK,let's go!试验对象是我第一个名为ST_Statistics的一张表,我要把我表里的数据导入到hdf ...

  7. Listener 监听Session内的对象

    Listener用于监控Session内的对象,分别是HttpSessionBindingListener与HttpSessionActivationListener.它们的触发时机分别为: Http ...

  8. Qt 程序打包发布总结

    1.  概述 当我们用QT写好了一个软件,要把你的程序分享出去的时候,不可能把编译的目录拷贝给别人去运行.编译好的程序应该是一个主程序,加一些资源文件,再加一些动态链接库,高大上一些的还可以做一个安装 ...

  9. 关于1KB病毒的清除

    以前中过很多次的1KB病毒,这种病毒来源一般都是U盘,就是去打印店插个U盘,回来插自己电脑发现U盘中毒了. 中毒特征就是根目录下的所有文件夹都变成快捷方式,都只有1KB大小,而根目录下的文件和压缩包不 ...

  10. (笔记)CanOpen协议【CanFestival】移植方法 支持VC、QT、STM32

    转自http://bbs.21ic.com/icview-878522-1-1.html   前段时间学习了CanOpen协议,到网上下载的CanFestival3-10源码,移植到VC.QT.STM ...