(一)手写spring IOC容器

本文用问答形式引导读者思考,以求理解spring ioc容器的设计思想

目录

  • IOC分析

    1. IOC是什么?
    2. 带来什么好处?
    3. 做什么工作?
    4. 是否是工厂模式的实例?
  • IOC设计实现

    1. IOC容器的工作?
      • bean是什么?
      • 它应该具备什么行为、功能?
      • 这个getBean()方法是否需要参数?需要几个参数?什么类型的参数?
      • getBean()方法返回值应该是什么类型?
    2. 设计bean工厂接口
    3. 如何告诉他创建Bean?
      • 定义一个bean定义注册接口
      • 接口中要定义什么方法?
      • 注册的bean定义用什么区分?
    4. 创建什么Bean?
      • bean定义的用途是什么?
      • 获得类实例的方式有哪些?
      • Bean工厂创建bean时需要知道哪些信息?
      • 单例还是多例?
      • bean定义应该提供哪些方法?
      • 对象交由IOC容器管理后生命周期还有什么事情要做?
    5. Bean工厂实现
      • 要具有什么功能?实现什么接口?
      • 创建的bean用什么存放?
      • getBean()方法要做什么?
      • bean定义信息如何存放?
      • bean定义是否可以重名?重名怎么办?
      • 扩展默认工厂
  • 画完整UML类图

  • 编写代码

  • 测试

  • 总结

IOC分析

1. IOC是什么?
	IOC:inversion of control 控制反转,也称依赖倒置反转。
	反转:依赖对象的获得权被反转了,由自己创建,变为从IOC容器获取,和自动注入。
2. 带来什么好处?
	- 代码简洁,不需要自己new很多类了。
	- 面向接口编程,使用者与具体类解耦,易扩展、替换实现者。
	- 可作为基础模块,供支撑其他高级功能
3. 做什么工作?
	负责创建、管理类实例,向使用者提供实例。
4. 是否是工厂模式的实例?
	是的。IOC容器负责创建bean实例,也称为bean工厂。

IOC设计实现

1. IOC容器的工作?
    - bean是什么?
		组件,就是类的实例对象。
    - IOC容器应该具备什么行为、功能?
  		负责创建、管理bean。他是一个bean工厂,负责对外提供bean实例,getBean()方法。
    - 这个getBean()方法是否需要参数?需要几个参数?什么类型的参数?
   		根据类的名称获取相应的bean是最简单的,也符合简单工厂设计,所以只用一个String参数即可。
    - getBean()方法返回值应该是什么类型?
  		返回的bean实例可能是所有的类型,所以应该是返回Object。
2.设计bean工厂接口
	目前只需要提供一个getBean()的方法。

BeanFactory

public interface BeanFactory {
	
	public Object getBean(String beanName) throws Exception;
}
  1. 如何告诉它创建bean?

    • 定义一个注册接口
    • bean定义注册接口应该定义什么方法?
      注册bean定义、获取bean定义、是否已包含bean定义。
    • 注册的bean定义应该如何区分?
      每个注册的bean定义有唯一的名称。
    • 类图
  2. 创建什么bean?

    • bean定义的用途是什么?
      告诉bean工厂该如何创建某bean。
    • 获得类实例的方式有哪些?
      new 构造方法
Student stu = new Student();
	工厂方法
public class StudentFactory{
	public static Student getStudent(){
		return new Student();
	}
}
	静态工厂方法
public class StudentFactory{
	public Student getStudent(){
		return new Student();
	}
}
		3. bean工厂创建bean时需要知道哪些信息?
			构造方法需要知道,类的全路径名(无参构造方法)。
			静态工厂方法需要知道,工厂类名和方法名。
			工厂方法需要知道,工厂bean名(可通过bean工厂获取工厂bean)和方法名。
		4. 单例还是多例?
			两种情况都有。
		5. bean定义应该提供哪些方法?
			- 获取bean的类名 getBeanClass():Class    有可能是bean的类名或工厂bean的类名
			- 获取工厂方法名 getFactoryMethodName(): String
			- 获取工厂bean名 getFactoryBeanName():String 
			- 是否单例等方法 getScope():String 、isSingleton():boolean、isPrototype():boolean
		6. 对象交由IOC容器管理后生命周期还有什么事情要做?
			可能要对bean实例化后进行初始化方法、销毁前进行的销毁方法
			故应定义getInitMethodName() 、getDestroyMethodName.

在这里插入图片描述
5. beanFactory实现
- 要实现什么功能?实现什么接口?
实现bean工厂和bean定义注册接口
- 创建的bean用什么存放,以便获取?
map
- getBean()要做哪些事?
创建bean实例,进行初始化等方法。
- bean定义信息用什么存放?
map
- bean定义是否可以重名,重名怎么办?
可以先简单设计为不可重名,重名即抛出异常。
- 扩展默认bean工厂
可以提前将单例bean初始化。

完整uml类图

在这里插入图片描述

编写代码

详见附件完整项目。

项目完整代码资源

测试

- 测试无参构造器创建bean
public class PreBuildBeanFactoryTest {

	static PreBuildBeanFactory bf = new PreBuildBeanFactory();

	@Test
	public void testConstrutor() throws Exception {
		GenericBeanDefinition bd = new GenericBeanDefinition();
		bd.setBeanClass(ABean.class);
		bd.setInitMethodName("init");
		bd.setDestroyName("destroy");
		bf.registry("abean", bd);
		bf.preInstantiateSingletons();
		
		ABean abean = (ABean)bf.getBean("abean");
		abean.doSomthing();
		
	}

在这里插入图片描述
- 测试静态工厂方法创建bean

@Test
	public void testStaticFactoryMethod() throws Exception {
		GenericBeanDefinition bd = new GenericBeanDefinition();
		bd.setBeanClass(ABeanFactory.class);
		bd.setFactoryMethodName("getABean");
		bf.registry("abean", bd);

		bf.preInstantiateSingletons();
		ABean abean = (ABean)bf.getBean("abean");
		abean.doSomthing();

	}

在这里插入图片描述
- 测试工厂方法创建bean

@Test
	public void testFactoryMethod() throws Exception {
		GenericBeanDefinition bd = new GenericBeanDefinition();
		bd.setFactoryMethodName("getABean2");
		bd.setFactoryBeanName("aBeanFactory");
		bf.registry("abean", bd);
		
		bd = new GenericBeanDefinition();
		bd.setBeanClass(ABeanFactory.class);
		bf.registry("aBeanFactory", bd);

		bf.preInstantiateSingletons();
		ABean abean = (ABean)bf.getBean("abean");
		abean.doSomthing();

	}

在这里插入图片描述

总结

本文是参考spring设计架构进行简化的方式来设计beanFactory,简化版的IOC容器,实现bean定义注册及获取功能,后续会继续实现DI、AOP等功能。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值