包办婚姻的Spring IoC

原创 2013年12月05日 23:35:04

基本概念

       IoC(Inversion of Control),直观地讲,就是对象创建或查找对象依赖的控制权由应用代码转到了外部容器,控制权的转移是所谓反转。使用Ioc,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。我们可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它


       IoC还有另外一个名字——“依赖注入DI(Dependency Injection)”。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,形象地说,即由容器动态地将某种依赖关系注入到组件之中。


IoC场景

      上面说的可能有点晕,来一个实际点的例子。


      丽萨已经老大不小了,一直没有男朋友,看着别人恩恩爱爱的,也不禁想找个BoyFriend。摆在她面前的有3种方案:主动“邂逅” Or 同事介绍 Or 父母包办。她会选择哪种呢?

      主动邂逅”方式,如图所示:


public class Girl { 

  public void kiss(){ 
    Boy boy = new Boy(); 
  } 

} 
       不过这种美好的纯洁的爱情,一般只会发生在校园里,对于已经是工薪阶层的丽萨显然不太适合。

      第二方案,同事介绍,

public class Girl { 

  void kiss(){ 
    Boy boy = BoyFactory.createBoy(); 
  } 
} 

       很多人都是这样找到了自己的另一半。丽萨以前也试着去跟同事介绍的handsome man接触过,但是真人与介绍的出入太大,最起码handsome这条就太符合,而且有他许多缺点。觉得他不适合自己,所以最后也就不了了之。


       所以无奈之下,她的难题丢给了父母。父母给她物色了一个“绝世好男人”——曾小贤(这娃有句经典台词:“好男人就是我,我就是....曾小贤”),终于算是遂了她的心愿了。

public class Girl { 

  void kiss(Boy boy){ 
    // kiss boy 
   boy.kiss(); 
  } 
} 

       虽然在现实生活中我们都希望与自己的另一半来场完美的邂逅,但在Spring世界里,跟丽萨一样,选择的却是父母包办,它就是控制反转,而这里具有控制力的父母,就是Spring所谓的容器概念。 


       典型的IoC可以如图所示。

 实例说明IoC注入方式

      IoC有3种注入方式:接口注入、Setter方法注入、构造器注入。由于接口注入不推荐使用,所以只介绍setter方法注入和构造器注入。


       用代码来说明一切吧:

【Girl.java】

package com.tgb;
/**
 * 期待找BF的Girl
 * @author Admin
 *
 */
public class Girl {

	private Boy bf;
	
	
	public Girl(){}
	
	public Girl(Boy bf){
		System.out.print("使用构造方法方式注入:");
		this.bf = bf;
	}
	
	public void setBf(Boy bf) {
		System.out.print("使用Setter方式注入:");
		this.bf = bf;
	}

	public void kissYourBF() {
		bf.kiss();
	}
}
【Boy.java】
package com.tgb;

/**
 * 合格的BF
 * @author Admin
 *
 */
public class Boy {

	public void kiss(){
		System.out.println("My boy friend,I'll kiss you!");
	}
}
【Client客户端】
package com.tgb;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Client {

	public static void main(String[] agrs){
		ApplicationContext factory = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		Girl lisa = (Girl)factory.getBean("girl");
		lisa.kissYourBF();
		
	}
}
【applicationContext.xml配置文件】
<?xml version="1.0" encoding="UTF-8"?>
<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="boy" class="com.tgb.Boy" />
	<bean id="girl" class="com.tgb.Girl">
		<!--构造器注入-->
		<constructor-arg ref="boy"></constructor-arg>
		<!--Setter方法注入-->
		<!--<property name="bf" ref="boy"></property>-->
	</bean>
</beans>

       选择Setter方法注入和构造器注入的控制是在配置文件中完成的。结果如下:




      Setter方法注入时,有2种装载方式需要注意,byName和byType。当我在配置文件中,把2种注入方式都注释掉,同时添加了default-autowire="byType",

<?xml version="1.0" encoding="UTF-8"?>
<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"
           default-autowire="byType"
           >

	<bean id="boy" class="com.tgb.Boy" />
	<bean id="girl" class="com.tgb.Girl">
		<!--构造器注入-->
		<!--<constructor-arg ref="boy"></constructor-arg>-->
		<!--Setter方法注入-->
		<!--<property name="bf" ref="boy"></property>-->
	</bean>
</beans>

       执行结果如图



       但是换成default-autowire="byName",则会报如下错误:


       这是为什么呢?原因在于,当使用byType方式装载时,Spring是根据classType来确定要实例化的类。所以就算bean的id是boy,跟Girl中bf的Setter名字不一致,依旧可以实例化。但是使用byName时,则是根据id来实例化类的。所以只要把Boy类对应的bean id跟Girl中的setter方法名一致才行,即修改id="boy"为id="bf",即可正常显示:

	<bean id="bf" class="com.tgb.Boy" />
	<bean id="girl" class="com.tgb.Girl">
		<!--构造器注入-->
		<!--<constructor-arg ref="boy"></constructor-arg>-->
		<!--Setter方法注入-->
		<!--<property name="bf" ref="boy"></property>-->
	</bean>

       另一种修改方式就是用显示的方式来设定Setter方法所注入的是哪个类的对象:

	<bean id="boy" class="com.tgb.Boy" />
	<bean id="girl" class="com.tgb.Girl">
		<!--构造器注入-->
		<!--<constructor-arg ref="boy"></constructor-arg>-->
		<!--Setter方法注入-->
		<property name="bf" ref="boy"></property>
	</bean>
       执行结果如图:


2种注入方式的比较

       Setter 注入:

    • 对于习惯了传统 javabean 开发的程序员,通过 setter 方法设定依赖关系更加直观。
    • 如果依赖关系较为复杂,那么构造子注入模式的构造函数也会相当庞大,而此时设值注入模式则更为简洁。
    • 如果用到了第三方类库,可能要求我们的组件提供一个默认的构造函数,此时构造子注入模式也不适用。

       构造器注入:

    • 在构造期间完成一个完整的、合法的对象。
    • 所有依赖关系在构造函数中集中呈现。
    • 依赖关系在构造时由容器一次性设定,组件被创建之后一直处于相对“不变”的稳定状态。
    • 只有组件的创建者关心其内部依赖关系,对调用者而言,该依赖关系处于“黑盒”之中。


版权声明:本文为博主原创文章,未经博主允许不得转载。如需转载请声明:【转自 http://blog.csdn.net/xiaoxian8023 】

包办婚姻的Spring IoC

转自:http://blog.csdn.net/xiaoxian8023/article/details/17148931 基本概念        IoC(Inversion of Contr...
  • Zhangxichao100
  • Zhangxichao100
  • 2017年05月25日 14:28
  • 184

Spring中IoC的基本概念(一)

什么是Ioc,spring中Ioc的基本概念
  • Veggiel
  • Veggiel
  • 2016年09月02日 11:24
  • 1076

简明扼要谈Spring IOC的好处

简明扼要谈Spring IOC的好处   IOC:控制反转,它是不是什么技术,它是一种设计模式。所谓控制反转就是由容器控制程序间的关系,而不是传统实现中,由编程代码直接操控。说白了就是由容...
  • u014802309
  • u014802309
  • 2015年01月06日 10:07
  • 1891

Spring IOC源码详解之容器初始化

Spring IOC源码详解之容器初始化 上篇介绍了Spring IOC的大致体系类图,先来看一段简短的代码,使用IOC比较典型的代码 ClassPathResource...
  • yujin753
  • yujin753
  • 2015年07月26日 08:51
  • 3420

spring中为什么要使用IOC

开篇前言 在前面的博文中,小编主要简单的介绍了spring的入门知识,随着学习的深入,我们知道spring最核心的两大技术,IOC和AOP,这两个技术也是spring最耀眼的地方,在后续的博文中...
  • sdmxdzb
  • sdmxdzb
  • 2016年08月04日 16:14
  • 2753

Spring IOC容器启动过程

IOC容器启动过程 资源定位(classpath,filesystem等) 载入,将bean定义转换为内部数据结构BeanDefintion 向IOC容器注册bean 资源定位定位配置文件,通过Bea...
  • sichenglain
  • sichenglain
  • 2016年12月18日 13:41
  • 551

Spring IOC(整体流程)

IOC容器基本分成BeanFactory和ApplicationContext两类 BeanFactory是基本,ApplicationContext多用在框架 继承结构如图: BeanFact...
  • zly9923218
  • zly9923218
  • 2016年05月03日 00:07
  • 1690

Spring中IOC配置xml实现和IOC注解实现

1.什么是spring spring 是分层的JavaSE/EE轻量级应用开源框架,已控制反转IOC和面向切面编程AOP为核心,提供了展现层SpringMVC, 和持久层Srping JDBC以及事务...
  • u014292162
  • u014292162
  • 2016年08月22日 16:10
  • 3286

[spring入门学习笔记][spring的IoC原理]

什么叫IoC控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency ...
  • zy691357966
  • zy691357966
  • 2016年04月13日 23:51
  • 1974

Spring深入浅出(二)IOC详解

IOC即inverse of control 控制反转 以前对象之间的引用是通过new来调用实现,有了Spring IOC,我们可以把对象之间的引用交给他来管理,这样就把控制权交给了Spring,所...
  • jwdstef
  • jwdstef
  • 2014年01月25日 15:40
  • 5023
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:包办婚姻的Spring IoC
举报原因:
原因补充:

(最多只允许输入30个字)