模仿 Spring 框架写一个简易 IoC 框架来深入理解 Spring 原理

内容目录

a. 简单了解 Spring

b. 讲解 IoC 概念

c. 解释 DI 概念

d. 通过案例来分析面向对象编程和面向接口编程的 IoC 区别

e. 案例源码的方式来模拟 Spring 可配置的方式来实现 IoC 容器

f. 测试自定义 Spring 框架用法

1. Spring 简述

1.1 什么是 Spring ?

​ Spring 是一个轻量级的开源的 JavaEE 框架,由作者 Rod Johnson 创建,兴起于 2003 年。目的是为了解决企业级开发的复杂性问题,Spring 出发点就是不重新造轮子,而是使现有的技术或框架更加易于使用。具有简单,易于扩展和维护和低耦合等特点。

​ Spring 的核心就是控制反转 ( IoC ) 和 依赖注入 (DI)及面向切面编程 (AOP) 。

1.2 什么是 IoC ?

​ IoC 就是控制反转(Inversion of Control ) 的缩写。它是软件设计中的一种设计原则和思想。可以有效的降低代码的耦合度,便于程序模块之间灵活组织和切换。实现了 “可插拔式” 的接口编程。降低了将来扩展及维护的成本。

​ IoC 的这种思想原则,可以形象比同于 “好莱坞原则”。不要给我们(好莱坞演艺公司)打电话,我们会给你打电话(don‘t call us, we‘ll call you)”这是著名的好莱坞原则。

​ 比如说,一个大碗儿明星A,在有些小公司演戏,往往可以自己决定要求公司提供什么资源,和什么人搭戏等等,公司就只能顺从大腕儿要求一一满足。这就是说大腕儿决定了他所依赖的资源及其他演员。

​ 而上面这种现象,在好莱坞是不适用的。再大的腕儿,所演的角色及搭配的演员等资源,都是由好莱坞公司来决定的,不是由大腕儿来决定的。这就是说,原来有演员的 **控制权反转 **了,反转交个公司了,由公司决定了!这就是所谓的好莱坞原则,这也正是所谓的 IoC 控制反转的概念。

1.3 什么是 DI ?

​ DI 为 Dependency Injection 的缩写,即“依赖注入”:组件之间依赖关系由容器在运行期决定。组件的创建都有容器来创建,再由容器来决定各组件之间的依赖关系。各个组件不再自己决定依赖的其他对象。话句话说,就是组件运行所依赖的对象只能是注入进来的对象,注入哪个对象,我就依赖哪个!简称 依赖注入

​ 再拿上面例子来说,在好莱坞,演员不能再自己决定自己和谁搭戏了,就是自己不再决定自己的依赖对象,而具体演戏时,依赖(搭戏)的是哪个一个演员,由公司分配(注入),公司给你注入是谁,那就和谁演。

​ 依赖注入是 IoC 实现的一种方式描述,IoC 和 DI 各从思想原则和方式上分别描述了解耦的这种编程模式。

2. 通过案例解释 IoC 的优势

2.1 下面来写一个耦合的、依赖具体实现的面向对象案例

​ 这里我们分别定义 显示器类 (GrayDisplay.java) 和 主机类 (Computer.java),其中主机类中直接依赖并实例化了显示器类。然后客户测试使用类 (Test.java)。它们的关系如下:

在这里插入图片描述

具体代码如下:

显示器类:

package com.ioc.demo1;
/**
 * 黑白显示器
 */
public class GrayDisplay {
   
	private int width = 1024;
	private int height = 786;
	/**
	 * 显示画面
	 */
	public void show(){
   
		System.out.println(width+"====显示器工作:显示黑白画面===="+height);
	}
}

主机类:

package com.ioc.demo1;

/**
 * 主机类
 */
public class Computer {
   
	//依赖了 具体的实现 
	private GrayDisplay display = new GrayDisplay();
	
	public void run(){
   
		System.out.println("======电脑启动=======");
		display.show();//点亮显示器 显示画面
		System.out.println("======电脑工作中...=========");
	}
}

测试类:

package com.ioc.demo1;

/**
 * 测试类
 *
 */
public class Test {
   
	public static void main(String[] args) {
   
		//实例化主机对象
		Computer computer = new Computer();
		//使用主机
		computer.run();
	}
}

分析:从上面的实现中可以看出,在 Computer 主机类中直接依赖并实例化了 GrayDisplay 显示器类对象。在客户使用过程中,如果想购买(实例化) 升级为彩色显示器,在不修改源码的前提下,是没办法更换的。如果为了更换显示器而修改类,则违背了设计模式的开闭原则

开闭原则: 对于扩展是开放的,但是对于修改是封闭

2.2 再来看下面向接口的、依赖倒置原则的实现方式

思路图示如下:

在这里插入图片描述

​ 下面实现思路是,先定义一个显示器接口 IDisplay,然后在定义 黑白显示器 GrayDisplay 和 彩色显示器 ColorDisplay 分别实现显示器接口。再定义主机类 Computer , 仅仅依赖接口 IDisplay 。最后在客户端测试类中分别实例化 显示器,主机对象,把显示器注入到主机对象。运行即可。

具体源码如下:

显示器接口:

package com.ioc.demo2;
/**
 * 显示器接口
 */
public interface IDisplay {
   
	public void show();
}

黑白显示器:

package com.ioc.demo2;
/**
 * 黑白显示器
 */
public class GrayDisplay implements IDisplay {
   
	private int width = 1024;
	private int height = 786;
	/**
	 * 显示画面
	 */
	public void show(){
   
		System.out.println(width+"====显示器工作:显示黑白画面===="+height);
	}
}

彩色显示器:

package com.ioc.demo2;
/**
 * 彩色显示器
 */
public class ColorDisplay implements IDisplay {
   
	private int width = 2048;
	private int height = 2000;
	/**
	 * 显示画面
	 */
	public void show(){
   
		System.out.println(width+"====显示器工作:显示彩色画面===="+height);
	}
}

主机:

package com.ioc.demo2;
/**
 * 	主机类
 * 	此类只依赖显示器的接口,在运行时,再决定依赖的被注入的对象,故名 依赖注入(DI)
 */
public class Computer {
   
	//这里只依赖了接口,并没有赋值具体的实例对象
	private IDisplay display;
	
	
	public void run(){
   
		System.out.println("======电脑启动=======");
		if(display == null){
   
			System.out.println("%%%%%%没有发现显示器,请检查连接!%%%%%%");
		}else{
   
			//这里的显示器对象,是使用者注入的对象。
			display.show();//点亮显示器 显示画面
		}
		System.out.println("======电脑工作中...=========");
	}
	
	/**
	 * 留一个显示器接口的插槽(注入对象的方式)
	 */
	public void setDisplay(IDisplay display){
   
		this.display = display;
	}
}

客户端测试:

package com.ioc.demo2;
/**
 * 使用者
 *	
 */
public class Test {
   
	public static void main(String[] args) {
   
		//先实例化主机对象 此时的主机中是没有显示器对象的
		Computer computer = new Computer();
		//实例化彩色显示器对象
		ColorDisplay display = 
  • 13
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zp8126

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值