Spring学习(七)深入理解Spring IoC容器
2016-05-26 23:35
666 查看
IoC:他是Spring容器的内核,AOP、声明式事务等功能都依赖于此功能,它涉及代码解耦,设计模式、代码优化等问题的考量。
接下来使用电影与演员的关系来详细解释一下IoC:
我们来使用电影《无间道》中刘德华所饰演的角色刘建明在天台对白来作为我们学习IoC的示例场景。
那么我们现在便有:
接口类:ActorArrangable、LiuJianming
Java Bean:WuJianDao
接口实现类:LiuDeHua实现LiuJianming接口
执行类:Director
在传统的表演模式中,是剧本与演员直接耦合。即剧本直接指定LiuDeHua来表演
那么在引入角色接口LiuJianming之后,类与类之间的关系变为:
在这种情况下,WuJianDao还是和角色LiuJianming、演员LiuDeHua之间存在耦合关系。
那么我们该如何实现让演员与剧本无关,即剧本只与角色有关,但却必须使LiuDeHua来完成角色的表演。
那么,我们便引入导演类Director
这时,由导演选择剧本,并为剧本定义一个角色LiuJianming,让LiuJianming这个角色插入到剧本当中去。
最后让LiuDeHua来饰演LiuJianming这个角色。
对应到软件当中,导演就像是一个装配器。他来安排演员表演具体的角色。
那么我们现在便可以来谈谈IoC的概念,
IoC从字面意思上可以理解为:
其一 控制
其二 反转
那到底是什么东西的控制被反转了呢?
对应到前面的例子
控制指的是选择LiuJianming角色扮演着的控制权
反转是指这种控制权从WuJianDao剧本中移除,转交到了导演的手中。
那么对于软件来说:就是对应某个接口的控制权从调用类当中来移除,转交到了第三方来决定。
由此也引出了DI的概念:让调用类对某一接口实现类的依赖关系由第三方注入,以移除调用类对某一接口实现类的依赖
接下来看一下IoC的注入类型
IoC从注入方法上看,主要划分为三种类型:
1.构造函数注入:通过调用类的构造函数,将接口实现类通过构造函数变量传入
2.属性注入:通过Setter方法完成调用类所需依赖的注入,更加灵活方便
3.接口注入:将调用类所有依赖注入的方法抽取到一个接口中,调用类通过实现该接口提供相应的注入方法。
由于采用接口注入需要额外声明一个接口,这无疑就增加了类的数目。
而且他的效果和属性注入并没有本质上的区别。所以,我们在Spring IoC当中并不提倡采用这种方式。
Spring作为一个容器,通过配置文件或者注解描述类和类之间的依赖关系,自动完成类的初始化和依赖注入的工作,
下面是对以上实例进行配置的配置文件:
那么,Spring为什么会有这种神奇般的力量呢?
仅凭一个简单的配置文件,就能魔法般的实现实例化并装配好程序所用的Bean呢。这种神奇的力量归功与JAVA语言本身的类反射功能。
下面,我们就来了解下JAVA语言的反射机制。
接下来使用电影与演员的关系来详细解释一下IoC:
我们来使用电影《无间道》中刘德华所饰演的角色刘建明在天台对白来作为我们学习IoC的示例场景。
那么我们现在便有:
接口类:ActorArrangable、LiuJianming
Java Bean:WuJianDao
接口实现类:LiuDeHua实现LiuJianming接口
执行类:Director
在传统的表演模式中,是剧本与演员直接耦合。即剧本直接指定LiuDeHua来表演
那么在引入角色接口LiuJianming之后,类与类之间的关系变为:
在这种情况下,WuJianDao还是和角色LiuJianming、演员LiuDeHua之间存在耦合关系。
那么我们该如何实现让演员与剧本无关,即剧本只与角色有关,但却必须使LiuDeHua来完成角色的表演。
那么,我们便引入导演类Director
这时,由导演选择剧本,并为剧本定义一个角色LiuJianming,让LiuJianming这个角色插入到剧本当中去。
最后让LiuDeHua来饰演LiuJianming这个角色。
对应到软件当中,导演就像是一个装配器。他来安排演员表演具体的角色。
那么我们现在便可以来谈谈IoC的概念,
IoC从字面意思上可以理解为:
其一 控制
其二 反转
那到底是什么东西的控制被反转了呢?
对应到前面的例子
控制指的是选择LiuJianming角色扮演着的控制权
反转是指这种控制权从WuJianDao剧本中移除,转交到了导演的手中。
那么对于软件来说:就是对应某个接口的控制权从调用类当中来移除,转交到了第三方来决定。
由此也引出了DI的概念:让调用类对某一接口实现类的依赖关系由第三方注入,以移除调用类对某一接口实现类的依赖
接下来看一下IoC的注入类型
IoC从注入方法上看,主要划分为三种类型:
1.构造函数注入:通过调用类的构造函数,将接口实现类通过构造函数变量传入
Public class WuJianDao { private LiuJianming ljm; //1:注入刘建明的具体扮演者 public WuJianDao(LiuJianming ljm) { this.ljm = ljm; } public void tianTai() { ljm.declare(“我想做一个好人!”) } } Public class Director { public void direct() { //2.指定角色的扮演者 LiuJianming ljm = new LiuDeHua(); //3.注入具体扮演者到剧本中 WuJianDao wjd = new WuJianDao(ljm); wjd.tianTai(); } }
2.属性注入:通过Setter方法完成调用类所需依赖的注入,更加灵活方便
Public class WuJianDao { private LiuJianming ljm; //1.属性注入方法 public void setLjm(LiuJianmin ljm) { this.ljm = ljm; } public void tianTai() { ljm.declare(“我想做一个好人!”) } } Public class Director { public void direct() { LiuJianming ljm = new LiuDeHua(); WuJianDao wjd = new WuJianDao(); //2.调用属性Setter方法注入 wjd.setLjm(ljm); wjd.tianTai(); }
3.接口注入:将调用类所有依赖注入的方法抽取到一个接口中,调用类通过实现该接口提供相应的注入方法。
Public interface ActorArrangable { void injectLjm(LiuJianming ljm); } Public class WuJianDao implements ActorArrangable { private LiuJianming ljm; //1.实现接口方法 public void injectLjm(LiuJianming ljm) {this.ljm = ljm; } public void tianTai() { ljm.declare(“我想做一个好人!”) } } Public class Director { public void direct() { LiuJianming ljm = new LiuDeHua(); WuJianDao wjd= new WuJianDao(); wjd.injectLjm(ljm); wjd.tianTai(); } }
由于采用接口注入需要额外声明一个接口,这无疑就增加了类的数目。
而且他的效果和属性注入并没有本质上的区别。所以,我们在Spring IoC当中并不提倡采用这种方式。
Spring作为一个容器,通过配置文件或者注解描述类和类之间的依赖关系,自动完成类的初始化和依赖注入的工作,
下面是对以上实例进行配置的配置文件:
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="ljm" class="cn.lovepi.chapter02.ioc.LiuDeHua"/> <bean id="wjd" class="cn.lovepi.chapter02.ioc.WuJianDao" p:geli-ref="ljm"/> </beans>
那么,Spring为什么会有这种神奇般的力量呢?
仅凭一个简单的配置文件,就能魔法般的实现实例化并装配好程序所用的Bean呢。这种神奇的力量归功与JAVA语言本身的类反射功能。
下面,我们就来了解下JAVA语言的反射机制。
相关文章推荐
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- Spring和ThreadLocal
- Spring Boot 开发微服务
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)
- 无线网卡安装DIY
- 模拟Spring的简单实现
- Spring整合WebSocket应用示例(上)
- spring+html5实现安全传输随机数字密码键盘
- Spring中属性注入详解
- springmvc 发送ajax出现中文乱码的解决方法汇总
- SpringMVC框架下JQuery传递并解析Json格式的数据是如何实现的
- struts2 spring整合fieldError问题
- spring的jdbctemplate的crud的基类dao
- 读取spring配置文件的方法(spring读取资源文件)
- Spring Bean基本管理实例详解