对spring控制反转以及依赖注入的理解

一、说到依赖注入(控制反转),先要理解什么是依赖。

Spring 把相互协作的关系称为依赖关系。假如 A组件调用了 B组件的方法,我们可称A组件依赖于 B组件

 

二、什么是依赖注入。

在传统的程序设计过程中,通常由调用者来创建被调用者的实例



在依赖注入的模式下。创建被调用者的工作不再由调用者来完毕,因此称为控制反转。创建被调用者实例的工作通常由Spring容器来完毕。然后注入给调用者。因此也称为依赖注入

自己理解:即一句话,由spring容器来控制组件A的调用的详细对象B。组件A依赖于spring容器的注入。

三、依赖注入的优点。

无论是依赖注入。还是控制反转,都说明Spring採用动态、灵活的方式来管理各种对象。

对象与对象之间的详细实现互相透明。在理解依赖注入之前,看例如以下这个问题在各种社会形态里怎样解决:一个人(Java实例。调用者)须要一把斧子(Java实例。被调用者) 

    
(1)原始社会里。差点儿没有社会分工。

须要斧子的人(调用者)仅仅能自己去磨一把斧子(被调用者)。相应的情形为:Java程序里的调用者自己创建被调用者。 

    
(2)进入工业社会,工厂出现。斧子不再由普通人完毕。而在工厂里被生产出来,此时须要斧子的人(调用者)找到工厂,购买斧子,无须关心斧子的制造过程。相应Java程序的简单工厂的设计模式。

 (此方法依赖于接口)
    (3)
进入按需分配社会,须要斧子的人不须要找到工厂,坐在家里发出一个简单指令:须要斧子。斧子就自然出如今他面前。相应Spring的依赖注入。 
     
第一种情况下,Java实例的调用者创建被调用的Java实例。必定要求被调用的Java类出如今调用者的代码里。无法实现二者之间的松耦合。

 
      
另外一种情况下,调用者无须关心被调用者详细实现过程,仅仅须要找到符合某种标准(接口)的实例。就可以使用。

此时调用的代码面向接口编程,能够让调用者和被调用者解耦,这也是工厂模式大量使用的原因。但调用者须要自己定位工厂,调用者与特定工厂耦合在一起。

 
  
情况下,调用者无须自己定位工厂。程序执行到须要被调用者时,系统自己主动提供被调用者实例。其实,调用者和被调用者都处于Spring的管理下。二者之间的依赖关系由Spring提供。 

   延时载入:容器在

依赖注入让 Spring Bean以被指文件组织在一起。而不是以硬编码的方式耦合在一起程序完毕无须理会被调用者的实现,也不无须主动定位工厂,这是最好的解耦方式

实例之间的依赖关系由 IoC 容器负责管理

    spring实现的主要原理:通过读取beanx.xml配置文件(有专门的工具类 elements),利用java的反射机制,生成相应的类对象(Object类型,然后能够用Object.getDeclaredMethods()来获取全部的方法名称。假设该方法名以set为开头,那么我们能够再读取配置文件里相应的属性,利用method.invoke()方法将属性注入到我们的对象其中。
   模拟实现方式能够參考一下博客

http://blog.csdn.net/it_man/article/details/4402245

四、依赖注入的 Spring实现

1、设值注入

设值注入是指 IoC容器使用属性的 setting方法来注入被依赖的实例。


先创建一个实体对象(Bean

[java] view plaincopy

1.     public class HelloWorld {    

2.         private String msg;    

3.         

4.         public String getMsg() {     

5.             return msg;    

6.         }    

7.         public void setMsg(String msg) {    

8.             this.msg = msg;    

9.         }    

10.  }   



再配置文件applicationContext.xml。实例化bean 

[java] view plaincopy

1.     <bean id="helloBean" class="com.spring.demo.HelloWorld">    

2.            <property name="msg" value="Hello World!"/>    

3.      </bean>   

最后測试是否可以得到注入的bean,并打印出对象的属性。

 

[java] view plaincopy

1.     public static void main(String[] args){    

2.             //读取配置文件。获得BeanFactory    

3.             ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");    

4.             BeanFactory factory = context;    

5.                 

6.             HelloWorld hello = (HelloWorld)factory.getBean("hello");    

7.                 

8.             System.out.println(hello.getMsg());     

9.      }   



2、构造注入

除了设值注入。还有还有一种注入方式,这样的方式在构造实例时,已为其完毕了依赖关系的初始化。

这样的利用构造器来设置依赖关系的方式,被称为构造注入。


先创建一个实体对象(Bean

[java] view plaincopy

1.     public class HelloWorld {    

2.         private String msg;    

3.         

4.         //须要一个默认无參构造器    

5.         public HelloWorld(){}    

6.             

7.         public HelloWorld(String msg){    

8.             this.msg = msg;    

9.         }    

10.          

11.      public String getMsg() {    

12.          return msg;    

13.      }    

14.      public void setMsg(String msg) {    

15.          this.msg = msg;    

16.      }    

17.  }   





再配置文件applicationContext.xml,实例化bean

[java] view plaincopy

1.     <bean id="hello" class="com.spring.demo.HelloWorld">      

2.          <constructor-arg index="0">     

3.                <value>HelloWorld!</value>     

4.            </constructor-arg>      

5.      </bean>   




最后測试是否可以得到注入的bean,并打印出对象的属性。

[java] view plaincopy

1.     public static void main(String[] args){    

2.             //读取配置文件,获得BeanFactory    

3.             ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");    

4.             BeanFactory factory = context;    

5.    

原文地址:https://www.cnblogs.com/zhchoutai/p/7192988.html