控制反转(Inversion of Control,缩写为IOC),它是把你设计好的对象交给spring控制,而不再需要你去手动 new Object(); 网上对于IOC的解释很多,对程序员而言,大篇文字的解释,不如代码举个例子:

  汽车(Car )、汽车车身 (CarBody) 、 汽车轮子(CarWheel )

  汽车 由 id + name +  车身 + 轮子 组成

  代码如下:

package com.wp;

public class Car {
private int id;
private String name;
private CarBody carbody;
private CarWheel carwheel;
// get set 方法省略。。。
}
package com.wp;

public class CarBody {
private int id;
private String name;
//get set 方法省略。。。
}
package com.wp;

public class CarWheel {
private int id;
private String name;
//get set 方法省略。。。
}

以往的方式:我们创建汽车对象是通过直接new Car(); 的方式去出动创建对象,也就是对象的创建是有我们程序去主动控制的。代码如下:

package com.wp.test;
import com.wp.Car;
public class TestSpring { public static void main(String[] args) {
Car car = new Car();
System.out.println(car); //输出 com.wp.Car@452b3a41
}
}

在Spring中,也可以让spring自动创建对象,代码如下:

首先在 applicationContext.xml 进行配置,配置class指向我们的Car 通过关键字c可以获取Car对象,并且会默认给Car对象的name属性赋值“小汽车”。

    <bean name="c" class="com.wp.Car">
<property name="name" value="小汽车" />
</bean>

测试类使用spring自动创建对象,代码如下:

package com.wp.test;
import com.wp.Car;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestSpring {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" });
Car car = (Car) context.getBean("c");
System.out.println(car.getName()); //输出 小汽车
}
}

  这种方式就是spring自动创建对象的方式,我们需要Car对象的时候,我们直接找Spring的IOC容器要就行了,我们不需要知道这个对象怎么创建的,我们需要就直接取。

通过上面的例子来解释一下 控制反转:

  以往的时候,Car对象是我们程序创建,需要手动 new Car()  来创建Car对象,Car的创建是由我们控制的;

  使用Spring 的IOC原理之后,Car对象由Spring 创建,我们需要的时候,直接去取,Car的创建由Spring 控制。

  对象的创建由我们控制转变为Spring控制,这种设计思想,就叫控制反转

依赖注入:

什么是依赖注入呢?简单点,程序员还是通过程序的方式来理解。

可以看到我们的 CarBody 和 CarWheel 还没派上用场,也就是我们在上面创建的小汽车的车身和轮子还都是空的,这个小汽车是无法使用的,为了让小汽车变的完整,我们要给小汽车创建车身和轮子组装上。还是通过以往的形式和依赖注入的形式来对比:

  以往的方式:

  我们会 new CarBody() ,然后通过Car的setCarBody() 把这对象放进去;

  然后再 new CarWheel () ,然后通过Car的setCarWheel()  把这对象放进去。
  一顿操作以后,我们的小汽车就完整了,代码如下:

package com.wp.test;
import com.wp.Car;
import com.wp.CarBody;
import com.wp.CarWheel; public class Test { public static void main(String[] args) {
Car car = new Car(); //创建小汽车
CarBody carbody = new CarBody(); //创建车身
CarWheel carwheel = new CarWheel(); //创建轮子

car.setCarbody(carbody); //给小汽车装上车身
car.setCarwheel(carwheel); //给小汽车装上轮子

System.out.println(car.getCarbody()); //输出 com.wp.CarBody@452b3a41
}
}

使用Spring 的依赖注入方式:

 修改applicationContext.xml 配置文件,通过前门spring创建小汽车对象的方式,把小汽车的车身和车轮也交给spring创建,然后通过 ref ="cb" 和 ref = "cw"的方式把车身和轮子组装到小汽车上。注意:cb 和 cw 分别对应 车身 、轮子 bean 的name

    <bean name="c" class="com.wp.Car">
<property name="name" value="小汽车" />
<property name="carbody" ref="cb" />
<property name="carwheel" ref="cw" />
</bean>
<bean name="cb" class="com.wp.CarBody">
<property name="name" value="豪华车身" />
</bean>
<bean name="cw" class="com.wp.CarWheel">
<property name="name" value="豪华轮子" />
</bean>

测试类如下:

package com.wp.test;
import com.wp.Car;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestSpring {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" });
Car car = (Car) context.getBean("c"); System.out.println(car.getName()); //输出 小汽车
System.out.println(car.getCarbody().getName()); //输出 豪华车身
System.out.println(car.getCarwheel().getName()); //输出 豪华轮子
}
}

  我们已经能够理解汽车是Spring创建的,通过 context.getBean("c") 可以直接获取汽车对象,也就是我们不需要创建对象,我们交给Spring去创建,我们需要用的时候,只管去向Spring容器要,Spring容器就会给我们一个创建好的对象。那么Spring 是如何把“车身”和“轮子”组装到“小汽车”上面呢,这就用到了依赖注入

  依赖注入(Dependency Injection)也是Spring框架的核心之一,缩写 DI ,

  在applicationContext.xml 配置文件中

    <bean name="c" class="com.wp.Car">
        <property name="name" value="小汽车" />
<property name="carbody" ref="cb" />
<property name="carwheel" ref="cw" />
</bean>

  首先看下name的赋值方式,创建Car对象时,要给 name 属性赋值,赋值方式是直接指定一个value="小汽车" 也就是创建一个Car对象,直接把小汽车这个字符串赋到Car对象的name属性上,小汽车就有名字了。

  然后看下 carbody 赋值方式,赋值方式是 ref = "cb" ,spring会自动去寻找name="cb"的 bean ,而这个bean 对应的实体类就是CarBody 类 ,在找到之后,Spring会创建CarBody 对象,然后把CarBody对象赋到 Car对象的carbody 属性上面, 小汽车就有车身了。

  CarWheel 原理与CarBody一样。

  Car 需要CarBody ,也就是Car 依赖CarBody ,Spring这种把 CarBody对象 注入到 Car 对象中的方式,就是依赖注入(DI)。

  那么spring是如何实现依赖注入呢?

  那就是反射(reflection) , <property name="carbody" ref="cb" /> 中的ref  就是反射的缩写,这个由spring自动完成,我们不需要去进行任何操作。

使用IOC 和 DI  有什么好处?

  以往的方式我们类里面主动创建对象,然后处理对象与对象的依赖,会导致类与类之间高耦合,使用IOC和DI 之后呢,我们把类的控制权交给Spring,Spring去进行创建对象并且进去对象依赖注入,我们只是在需要的时候去找Spring的IOC容器去取,可以让我们的系统结构更加灵活。

另外:

如果感觉配置文件写的不方便,也可以写成注解的方式:

applicationContext.xml

<context:annotation-config/>

Car 的属性上增加@Autowired注解
package com.wp;

import org.springframework.beans.factory.annotation.Autowired;

public class Car {
private int id;
private String name;
@Autowired
private CarBody carbody;
@Autowired
private CarWheel carwheel;
  //get set 方法省略。。。
}

注解运行结果与配置文件运行结果一致。
加油!

Spring IOC&DI 控制反转和依赖注入的更多相关文章

  1. IOC/DI控制反转与依赖注入

    IOC/DI控制反转与依赖注入 IOC和DI表现的效果的是一样的只不过对于作用的对象不同,有了不一样的名字. 先用一个现实的例子来说明IOC/DI表现出来的效果.

  2. 工厂方法模式与IoC/DI控制反转和依赖注入

    IoC——Inversion of Control  控制反转 DI——Dependency Injection   依赖注入 要想理解上面两个概念,就必须搞清楚如下的问题: 参与者都有谁? 依赖:谁 ...

  3. 轻松了解Spring中的控制反转和依赖注入(二)

    紧接上一篇文章<轻松了解Spring中的控制反转和依赖注入>讲解了SpringIOC和DI的基本概念,这篇文章我们模拟一下SpringIOC的工作机制,使我们更加深刻的理解其中的工作. 类 ...

  4. Spring中的控制反转和依赖注入

    Spring中的控制反转和依赖注入 原文链接:https://www.cnblogs.com/xxzhuang/p/5948902.html 我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达 ...

  5. 轻松了解Spring中的控制反转和依赖注入(一)

    我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达170平方米,重达30吨,到现如今的个人笔记本,事物更加轻量功能却更加丰富,这是事物发展过程中的一个趋势,在技术领域中同样也是如此,企业级Ja ...

  6. Spring框架之控制反转和依赖注入

    学Spring框架必须理解控制反转和依赖注入.下面各自举一个例子,来说明控制反转和依赖注入. IOC(控制反转):应用本身创建和维护的依赖对象:现在交由外部容器(Spring)来创建和维护:这个控制权 ...

  7. Spring是什么+控制反转和依赖注入

    Spring是一个开源框架,是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架. 原因: (1)通过控制反转(IOC)达到松耦合,IOC也就是把控制权交出去,在使用中直接得到对象 (2)提 ...

  8. IOC和DI 控制反转和依赖注入

    首先要分享的是Iteye的开涛这位技术牛人对Spring框架的IOC的理解,写得非常通俗易懂,以下内容全部来自原文,原文地址:http://jinnianshilongnian.iteye.com/b ...

  9. Spring学习02——控制反转、依赖注入

    有两个人,张三和李四 package com.su.service; public class ZhangSan implements Tester{ public void test(){ Syst ...

随机推荐

  1. P7444-「EZEC-7」猜排列【dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P7444 题目大意 一个长度为\(n\)的排列,已知每个\(c_i\)表示那个排列中\(mex\)为\(i\)的区间 ...

  2. Redis之品鉴之旅(五)

    Redis事务 原子性:就是最小的单位 一致性:好多命令,要么全部执行成功,要么全部执行失败 隔离性:一个会话和另一个会话之间是互相隔离的 持久性:执行了就执行了,数据保存在硬盘上 典型例子:银行转账 ...

  3. Node.js躬行记(12)——BFF

    BFF字面意思是服务于前端的后端,我的理解就是数据聚合层.我们组在维护一个后台管理系统,会频繁的与数据库交互. 过去为了增删改查会写大量的对应接口,并且还需要在Model.Service.Router ...

  4. Idea热部署功能

    什么是Idea自动热部署? 热部署是指代码改动之后,调试过程中会服务自动重启,减少手动重启的麻烦,尤其是在微服务开发中,涉及到很多模块的调试更为重要. 如何开启热部署功能? 1.添加如下依赖到项目模块 ...

  5. spring boot log4j2 最佳实践

    为什么选择 log4j2 Log4j2 使用了 LMAX Disruptor 库.在多线程场景中,异步 Logger 的吞吐量比 Log4j 1.x 和 Logback 高 18 倍,延迟低几个数量级 ...

  6. 内网渗透DC-5靶场通关

    个人博客地址:点我 DC系列共9个靶场,本次来试玩一下一个 DC-5,只有一个flag,下载地址. 下载下来后是 .ova 格式,建议使用vitualbox进行搭建,vmware可能存在兼容性问题.靶 ...

  7. JDK 8中重要的函数式接口(必知必会)

    JDK 8 提供的重要函数式接口: Consumer (消费者) 功能:接收一个对象,返回void. 定义:void accept(T t) 默认方法:Consumer andThen(Consume ...

  8. vue3.x全局插件和组件

    做vue项目的时候,总有一些小组件或者工具类,我们需要频繁的使用,每个使用的地方再去引用相对比较麻烦,当然也有一些好处,尤其是配合组件异步加载的时候,能最更好的减少项目首次加载的体积,从而优化一些体验 ...

  9. [对对子队]会议记录5.18(Scrum Meeting5)

    今天已完成的工作 何瑞 ​ 工作内容:搭建第8关 ​ 相关issue:搭建关卡7.8.9 ​ 相关签入:feat:初步搭建了Lv8 吴昭邦 ​ 工作内容:搭建第8关 ​ 相关issue:搭建关卡7.8 ...

  10. oo第四单元及期末总结

    一.第四单元作业架构总结 第一次UML作业: 在分析各指令所需要的信息后建立了类(class),操作(operation),属性(Attribute)这几个类用来存储分析后的结果,而接口在本次作业中与 ...