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

我们常提起的依赖注入(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. 【转】HTML <!--...--> 注释 、CSS/JS //注释 和 /*.....*/ 注释

    原文地址:http://www.cnblogs.com/iceflorence/p/5815409.html <!-- -->是HTML的注释标签,使用 < 和 > 是符合HT ...

  2. 解析Google集群资源管理系统Omega

    1. 背景 Google的第一代/第二代集群(资源)管理系统被称为Borg,Borg设计细节因零零星星出现在各种文章中而知名,但一直未公开(比如发一篇paper).然而,我们可从腾讯公布的Torca( ...

  3. Spring Boot 自定义属性 以及 乱码问题

    自定义属性 使用随机数及自定义配置类 中文乱码问题 1添加配置 2设置文件类型 1IDEA 2eclipse 自定义属性 application.properties提供自定义属性的支持,这样我们就可 ...

  4. 多变量频率统计——r

    例如有X1,X2,..,Xn个变量,我需要对每一个变量进行频次统计,如果一个一个求解的话非常麻烦,如table(X1), table(X2), ... ,table(Xn).有没有简单的语句一次性求解 ...

  5. Python中sorted()方法的用法

    Python中sorted()方法的用法 2012-12-24 22:01:14|  分类: Python |字号 订阅 1.先说一下iterable,中文意思是迭代器. Python的帮助文档中对i ...

  6. 【2】JVM-JAVA对象的访问

    Java中对象的访问 JAVA是面向对象的语言,那么在JAVA虚拟机中,存在非常多的对象,对象访问是无处不在的.即时是最简单的访问,也会涉及到JAVA栈.JAVA堆.方法区这三个非常重要的内存区域之间 ...

  7. 动态SQL是什么??什么是静态SQL,动态SQL的动态体现在哪里???

    首先,所谓SQL的动态和静态,是指SQL语句在何时被编译和执行,二者都是用在SQL嵌入式编程中的,这里所说的嵌入式是指将SQL语句嵌入在高级语言中,而不是针对于单片机的那种嵌入式编程.在某种高级语言中 ...

  8. 第三百三十二节,web爬虫讲解2—Scrapy框架爬虫—Scrapy使用

    第三百三十二节,web爬虫讲解2—Scrapy框架爬虫—Scrapy使用 xpath表达式 //x 表示向下查找n层指定标签,如://div 表示查找所有div标签 /x 表示向下查找一层指定的标签 ...

  9. JUnit介绍,JUnit是什么?

    JUnit是什么? JJUnit是用于编写和运行可重复的自动化测试的开源测试框架, 这样可以保证我们的代码按预期工作.JUnit可广泛用于工业和作为支架(从命令行)或IDE(如Eclipse)内单独的 ...

  10. e782. 排列JList中的项

    By default, the items in a list are arranged vertically, in a single column, as in: item1 item2 ... ...