【spring】——依赖注入

来源:互联网 发布:php 二进制 编辑:程序博客网 时间:2024/05/26 19:17

理解分析

   

   依赖注入(Dependency Injection)即控制反转(Inversion of Control ,IoC),是spring的核心机制。


    在传统的程序设计过程中,当某个实例(调用者)需要另一个实例(被调用者)时,通常由调用着来创建被调用者的实例。而在依赖注入的模式下,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者实例的工作通常由spring容器来完成,然后注入调用者,因此也称为依赖注入。这说明Spring采用动态、灵活的方式来管理各种对象。


    在机房收费系统里,当我们调用一个类的时候都是直接new的,就好比原始社会里需要斧子,就得自己去创建。


   后面学了设计模式后,我们就运用了简单工厂设计模式来把这些类放到工厂里,用到的时候直接通过过程来寻找。就好比工业社会,工厂出现,我们可以直接购买,无需自己生产。但我们还是要找到商店,也就是还要定位,调用者和工厂耦合在一起了。


     之后伟大的马克思为我们设想了共产主义社会,我们都不用定位工厂,坐等社会提供即可了。也就是说我们不用关心斧子的生产、定位工厂,实例之间的依赖关系由IOC容器负责软了,等待Spring依赖注入。


注入方式

   经过一翻理解,算是把依赖注入理解了。依赖注入有两种方式:


设值注入

    IOC容器使用属性的setter方法来注入被依赖的实例。


  栗子:


  Person:


package com.demo.person;public interface Person {public void userAxe();}





  Axe:


package com.demo.axe;public interface Axe {public String chop();}




  AxeImpl:


package com.demo.axe;public class AxeImpl implements Axe {public String chop() {return "砍柴又慢又沉!";}}



PersonImpl


package com.demo.person;import com.demo.axe.Axe;public class PersonImpl implements Person {private Axe axe;public void userAxe() {System.out.println(axe.chop());}public void setAxe(Axe axe) {this.axe = axe;}}




   spring配置文件beans.xml


<?xml version="1.0" encoding="UTF-8"?><!--  - Application context definition for JPetStore's business layer.  - Contains bean references to the transaction manager and to the DAOs in  - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").  --><beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:aop="http://www.springframework.org/schema/aop"     xmlns:tx="http://www.springframework.org/schema/tx"     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"><!-- 配置person实例,其实现类是PersonImpl --!><bean id="perSon" class="com.demo.person.PersonImpl"><property name="axe" ref="stoneAxe"/></bean><bean id="stoneAxe" class="com.demo.axe.AxeImpl"/></beans>




测试类:

package test;import org.springframework.beans.factory.BeanFactory;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.demo.person.Person;public class BeanTest {public static void main(String[] args) {BeanFactory factory = new ClassPathXmlApplicationContext("beans.xml");Person perSon=(Person)factory.getBean("perSon");perSon.userAxe();}}



输出结果:



 

构造注入

   IOC容器使用构造器来注入被依赖的实例。这种方式在构造实例时,已经为其完成了依赖关系的初始化。


  栗子:接口和AxeImpl的代码和设置注入的相同


   PersonImpl


package com.demo.person;import com.demo.axe.Axe;public class PersonImpl implements Person {private Axe axe;//默认的构造器public PersonImpl(){}//构造注入所需的带参数的构造器public PersonImpl(Axe axe){this.axe=axe;}//实现person几口的useAxe方法public void userAxe() {//表明person对象依赖于axe对象System.out.println(axe.chop());}}




   spring配置文件beans.xml

  

<?xml version="1.0" encoding="UTF-8"?><!--  - Application context definition for JPetStore's business layer.  - Contains bean references to the transaction manager and to the DAOs in  - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").  --><beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:aop="http://www.springframework.org/schema/aop"     xmlns:tx="http://www.springframework.org/schema/tx"     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"><bean id="perSon" class="com.demo.person.PersonImpl"><constructor-arg ref="stoneAxe"/></bean><bean id="stoneAxe" class="com.demo.axe.AxeImpl"/></beans>


  测试类和实现结果与设值注入相同。


对比两种注入方式


   在配置文件中设值注入用<property>标签实现,而构造注入用<constructor-arg>标签实现。


     设值注入与传统的JavaBean的写法更为相似,更容易理解和接受,setter方法设定依赖关系显得更加直观自然。对于复杂的依赖关系,如果采用构造注入,会导致构造器过于臃肿难以阅读。而构造器在构造实例是,就要完成依赖关系的初始化,这样会影响系统的性能。而设值注入可以避免。在有某些属性可选的情况下,多参数的构造器更加笨重。


    构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入。对于依赖关系无须变化的Bean,因为没有 setter方法,所有的依赖关系全部在构造器内设定。因此,无须担心后续的代码对依赖关系产生破坏。构造注入的组件内部依赖关系完全透明,更符合高内聚的原则。


总结

    依赖注入就是使用spring容器来管理实例之间的依赖关系,这样调用者就可以不用自己去new被调用者,也不用自己去定位工厂,坐等spring提供即可。




0 0