【spring】——依赖注入

理解分析

   

   依赖注入(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提供即可。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值