文档章节

spring学习3-Ioc和DI的简单介绍

大嘴吃鸡腿
 大嘴吃鸡腿
发布于 2014/03/16 15:52
字数 1243
阅读 170
收藏 0

控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心。 控制反转还有一个名字叫做依赖注入(Dependency Injection)。简称DI

以上是来自于百度百科中关于IOC和DI的简单介绍,从中我们可以看到ioc的主要作用是减少类与类之间的耦合程度,在spring中,ioc的表现为类的实例化由原本程序员自己创建对象的动作转为由spring容器创建对象。

在不使用IOC的情况下,我们实例化一个类


   
IEngine engine = new QiyouEngine();

在这个语句中我们用到了IEngine接口和其实现类QiyouEngine,这样这个类就需要引用这两个类,如果需要改动实现类,则需要修改代码,这就违反了面向对象设计中的”开闭原则“。想要解耦这段代码,一般的解决可以使用工厂模式对其解耦


   
1 public class Main{ 2 public static void main(String args[]){ 3 IEngine engine = EngineFactory.getEngine(); 4 engine.doSomething(); 5 } 6 } 7 8 9 public class EngineFactory{ 10 public static getEngine(){ 11 return new QiyouEngine(); 12 } 13 }

如果再进一步,可以使用工厂模式+配置文件+反射来实现

比如我们的配置文件叫config.property,里面配置

engine=com.example.QiyouEngine;

在工厂中我们就可以修改成


   
1 public class EngineFactory { 2 3 public static IEngine getEngine() throws Exception{ 4 // 读取配置文件 5 Properties prop = new Properties(); 6 String rootPath = System.getProperty( " user.dir " ); 7 File f = new File(rootPath + File.separator + " config " + File.separator + " config.property " ); 8 InputStream in = new BufferedInputStream( new FileInputStream(f)); 9 prop.load(in); 10 String className = prop.getProperty( " engine " ); 11 12 // 根据反射获得类 13 IEngine engine = (IEngine) Class.forName(className).newInstance(); 14 return engine; 15 } 16 }

这样只要修改配置文件中的实现类名就可以修改程序中的实现类,从而达到不用修改代码的目的。

和上面的例子相似,spring也有着自己的配置文件。

这里我在src目录下创建了一个applicationContext.xml配置文件,其内容是


   
1 <? xml version="1.0" encoding="UTF-8" ?> 2 < beans xmlns ="http://www.springframework.org/schema/beans" 3 xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation ="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd" > 6 7 < bean id ="engine" class ="com.demo.spring.car.QiyouEngine" > 8 </ bean > 9 </ beans >

 

在代码中我们可以这么写:


   
1 public static void main( String[] args ) 2 { 3 ApplicationContext context = new ClassPathXmlApplicationContext( " applicationContext.xml " ); 4 IEngine engine = (IEngine) context.getBean( " engine " ); 5 engine.doSomething(); 6 }

这和刚刚的效果是一样的。

如果大家在找IOC的时候一般都会伴随着DI这个词,在spring中,ioc和di是紧密联系的,下面我们演示一下DI是什么样子的。

现在有一个类叫QiyouEngine,其中有个属性是发动机的排量cc,如果一般的写法,我们会在对象创建后通过调用set方法,把值塞到对象中,在spring中可以在配置文件中实现。我们修改一下刚刚xml文件在engine bean中添加属性:


   
< bean id ="engine" class ="com.demo.spring.car.QiyouEngine" > < property name ="cc" value ="2.0" ></ property > </ bean >

在代码中我们加入cc成员变量,并为其添加set的方法


   
1 public class QiyouEngine implements IEngine { 2 3 private String cc; // 排量 4 5 public String getCc() { 6 return cc; 7 } 8 9 public void setCc(String cc) { 10 this .cc = cc; 11 } 12 13 public void description() { 14 System.out.println( " 我是汽油发动机\n " + this .toString()); 15 } 16 17 @Override 18 public String toString() { 19 return " QiyouEngine [cc= " + cc + " ] " ; 20 } 21 22 }

在创建完对象后,spring会自动调用set的方法把值塞入对象中。

再运行一边Main类,结果如下

image

当然,我们注入的不知是常量,也可以注入其他的类。

比如现在我们有一个类叫Car,它有两个属性,一个是name,另一个是engine,我们要做的就是把刚刚的QiyouEngine注入到Car中


   
< bean id ="car" class ="com.demo.spring.car.Car" > < property name ="name" value ="宝马" ></ property > < property name ="engine" ref ="engine" ></ property > </ bean >

图片中可以看到engine用的是ref,而不是value,这个就是引用其他类的关键

main类我们修改一下,直接获得car类


   
public static void main( String[] args ) { ApplicationContext context = new ClassPathXmlApplicationContext( " applicationContext.xml " ); Car car = (Car) context.getBean( " car " ); System.out.println(car); }

Car类的定义


   
public class Car { private IEngine engine; private String name; public String getName() { return name; } public void setName(String name) { this .name = name; } public IEngine getEngine() { return engine; } public void setEngine(IEngine engine) { this .engine = engine; } @Override public String toString() { return " Car [engine= " + engine + " , name= " + name + " ] " ; } }

运行结果:

image

 

在bean标签里其实还有个属性scope,这个属性可以说是标识这个通过spring ioc获取的类的生命周期,其默认值是单例(Singleton),不过我们执行多少次context.getBean(“engine”),获得的都是同一个对象,这个属性一共有四个值

  • singleton:单例(默认)
  • prototype:每次调用一次getBean方法,就new一个对象出来
  • request:用于web开发将bean放入request中,在同一个request中获取的是同一个bean
  • session:用于web开发将bean放入session中。

有关ioc和DI跟深入的使用,待我学习完再和大家分享。

© 著作权归作者所有

大嘴吃鸡腿
粉丝 10
博文 13
码字总数 7700
作品 0
厦门
程序员
私信 提问
三条路线告诉你如何掌握Spring IoC容器的核心原理

一、前言 前三篇已经从历史的角度和大家一起探讨了为什么会有Spring,Spring的两个核心概念:IoC和AOP的雏形,Spring的历史变迁和如今的生态帝国。本节的主要目的就是通过一个切入点带大家一...

Java小铺
2018/08/27
0
0
【转载】轻松学习Spring: IoC容器和Dependency Injection模式

最近公司需要,项目中要用到Spring和Ibatis。趁着过年好好学习学习。Ibatis就如同Hibernate一样的持久层技术,学习起来难度不大,但Spring可不一样,揣着Ioc,DJ和AOP,四处走红。学起来可不...

Start-up
2012/05/17
0
0
控制反转和依赖注入的理解(通俗易懂)

学习过Spring框架的人一定都会听过Spring的IoC(控制反转) 、DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC 、DI这两个概念是模糊不清的,是很难理解的,今天和大家分享网上的一...

小橙子的曼曼
03/20
0
0
轻松学习Spring IoC容器和Dependency Injection模式(转)

转载:Bromon的blog 下面就是引用他说的话: IoC与DI   首先想说说IoC(Inversion of Control,控制倒转)。这是spring的核心,贯穿始终。所谓IoC,对于spring框架来说,就是由spring来负责...

zgyin688
2012/10/09
0
0
Spring IoC & DI

IOC诞生的历史 在没有IoC时,关联不同模块是通过类实例实现的,代码可能是这样子的: 当YourServiceImpl的接口不变时,只需要根据业务需要更换不同的YourService实现类即可。一旦更换实现类时...

classfly
2018/06/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java的线程同步和并发问题示例

并发问题 多线程是一个非常强大的工具,它使我们能够更好地利用系统的资源,但我们需要在读取和写入多个线程共享的数据时特别小心。 当多个线程尝试同时读取和写入共享数据时,会出现两种类型...

hiuh
今天
1
0
Spring Boot 常用注解说明

实体类 @Entity (实体类注解) @Table(可指定表名) @Data(可缺省get/set) @Id (指定属性主键) @GeneratedValue(指定主键生成规则)

兜兜毛毛
今天
3
0
局域网能互相ping通,ubuntu虚拟机不能上外网

【问题】 桥接模式老是无法上网,查看本机IP发现被分配了一个私网地址,猜测应该是虚拟DHCP服务器没有打开,于是查看Ubuntu的网络配置: /etc/network/interfaces 发现没有dhcp配置的信息,只...

tahiti_aa
今天
2
0
以太坊助记词PHP开发包简介

以太坊助记词PHP开发包用来为PHP以太坊应用增加助记词和层级确定密钥支持能力。下载地址:以太坊助记词php开发包 。 1、开发包概述 以太坊助记词PHP开发包主要包括以下特性: 生成符合BIP39...

汇智网教程
昨天
4
0
系统监控-分布式调用链Skywalking

1. 为什么要使用分布式调用链技术? 随着公司业务的高速发展,公司服务之间的调用关系愈加复杂,如何理清并跟踪它们之间的调用关系就显的比较关键。线上每一个请求会经过多个业务系统,并产生...

秋日芒草
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部