模拟SpringIOC准备

Bean基础类

BeanDefinition

BeanDefinition是Bean的元数据,它定义了Bean的Class类型、name、bean的属性集合、bean的实例。

Bean在IOC容器中的定义,IOC容器可以根据这个来定义来生成实例。以BeanDefinition类为核心散发出的几个类,都是用于解决Bean的基本定义问题,包括他的类型、属性赋值等

PropertyValue

它封装了Bean的属性,它有两个成员变量:String name,Object value。对应着Spring的XML配置文件中的Property中的name和value:

如果value是ref时,要先解析,转换成BeanReference放入value

BeanReference

用于标识property标签的ref属性里的对象。

BeanPostProcessor [interface]

BeanPostProcessor接口用于bean定义初始化时的嵌入操作,如postProcessorAfterInitialization、postProcessorBeforeInitialization方法,解决在Ioc容器如何植入Aop的问题

Bean工厂

BeanFactory [interface]

标识一个Ioc容器,以BeanFactory为接口的实体类,都用于解决Ioc容器在已经过去Bean的定义时,解决如何装配、获取实例的问题。

它有一个方法,getBean(name),通过name获取Bean实例

AbstractBeanFactory

BeanFactory的抽象实现,规范了Ioc容器的基本结构,如下:

beanDefinitionMap,Map类型,以Bean的name为key存放着Bean的定义信息

branDefinitionName,List类型,存放着完成注册的bean的name

benPostProcessors:List类型,增加bean处理程序,例如通过postProcessorAfterInitialization、postProcessorBeforeInitialization实现AOP

getBean(String name),根据名字获取bean的实例。首先根据名称获取beanDefinition,如果获取不到,则抛出没有这个bean定义的异常,检查bean是否装配,没有装配的话,先craeteBean获取Bean的class,通过newInstance()方法创建实例,调用装配的钩子方法,初始化bean,生成相关代理类,用于实现aop织入,放到beanDefinition的value中,接着实现装配,让子类去实现。

initializeBean(Object bean, String name),初始化bean执行bean处理器,生成相关代理类,遍历BeanPostProcessor,执行其方法

preInstantiateSingletons,实例化Bean,遍历beanDefinitionName获取beanDefinition的name后通过getBean(name)方法实例化bean

getBeansForType(Class type),根据类型获取所有bean实例,遍历beanDefinitionName,获取Beandefinition,判断此bean是否为指定class参数所表示的类或接口是否相同,或是否是其超类或超接口

registerBeanDefinition(String name,BeanDefinition beanDefinition),添加到beanDefinitionMap和beanDefinitionNames中

addBeanPostProcessor(BeanPostprocessor beanPostProcessor) 增加Bean处理程序。

BeanFactoryAware

setBeanFactory(beanFactory),实现该接口则有操作BeanFactory的能力,

AutoWireCapableBeanFacotry

AbstractBeanFactory的子类,可以实现自动装配的BeanFactory。

applyPropertyValues(Object bean, BeanDefinition beanDefinition),判断该bean参数是否是BeanFactoryAware的实现类,如果是,则将该bean设置到BeanFactory里

遍历PropertyValue,获取value,判断该value是否为BeanReference的实现类,若是则将该value强转BeanReference,跟Beanreference的name调用getbean,获取实例。

根据参数bean获取class,通过getDeclaredMethod()方法获取setXXX方法,invoke该方法将value注入。

解析xml

ResourceLoder

资源加载类,通过给定名称查找资源返回inputStream

BeanDefinitionReader [interface]

解析BeanDefinition的接口,暴露加载bean的方法

locadBeanDefinitions(String location)根据地址加载bean的定义

AbstractBeanDefinitionReader

BeanDefinitionReader接口的实现类,规范了BeanDefinitionReader的基本接口

Registry 键值存储的IOC容器(beanDefinitionMap)

ResourceLoader,资源加载类

XmlBeanDefinitionReader

AbstractBeanDefinitionReader的实现类,从XMl中读取bean的定义,实现了loadBeanDefinitions()方法

loadBeanDefinitions(),获取资源输入流,解析为Document,获取根,获取下的所有bean,遍历,获取bean标签的id属性作为bean的name,获取bean标签的class属性作为classname,创建beanDefinition,解析bean标签下的property子标签,遍历,获取name和value设置到beanDefinition中的propertyvalues,如果存在ref属性呢,则获取ref属性,做空校验,创建新的beanReference添加到PropertyValues,最后把name和classname放置到BeanDefinition中。

ApplicationContext

以ApplicationContext为接口的实现类,主要对Resource、BeanFactory进行了功能封装,解决根据地址获取资源通过IOC容器注册Bean定义并且实例化的问题。

AbstractApplicationContext

ApplicationContext的抽象实现,定义了创建bean的一些操作,AbstractBeanFactory成员变量。

Refresh()实现BeanFactory的刷新,加载出bean的定义保存到BeanFactory中,并实例化,初始化。

loadBeanDefinitions,加载出Bean的定义到beanFactory中

registerBeanPostProcessors,加载bean的处理器,用beanFactory的getBeansForType获取实现BeanPostProcessor接口的类,注册到abstractBeanFactory维护的beanPostProcessor列表中去,在通过getBean方法调用initializeBean,初始化bean处理器

onRefresh,实例化所有bean

getBean,根据名字获取bean

ClassPathXmlApplicationContext

从类路径加载资源,继承AbstractApplicationContext,实现loadBeanDefinitions方法,使用xmlBeanDefinitionReader将xml中的bean注册到BeanDefinitionMap里

流程描述:

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("tinyioc.xml");

HelloWorldService helloWorldService = (HelloWorldService) applicationContext.getBean("helloWorldService");

helloWorldService.helloWorld();

ClassPathXmlApplicationContext,继承AbstractApplicationContext,根据xml路径解析bean,有两个构造方法:路径和装配模式,默认使用自动创配模式,在构造函数里会调用父类refresh来完成创建bean的一些操作。ClassPathXmlApplicationContext重写了loadBeanDefinitions方法,使用XmlBeanDefinitionReader将xml中的信息加载到内置的IOC容器,

Refresh是其父类AbstractApplicationContext的方法,实现BeanFactory刷新逻辑,也就是告诉BeanFactory使用哪个资源加载Bean定义,并实例化,初始化。在此会调用loadBeanDefinitions方法加载bean定义,调用registerBeanPostProcessors来加载bean处理器,到这里bean的xml解析到加载都已经完成了,接着onRefresh方法调用beanfactory的preInstantiateSingletons方法来实例化所有bean。

preInstantiateSingletons是AbstractBeanFactory的方法,它会循环BeanDefinitionName,根据得到的名称,调用getBean方法。

getBean(name)根据名称获取bean,它主要完成了,bean的实例化,装配,执行bean的处理器等

设计模式的思想:

策略模式

AbstractBeanFactory中有个applyPropertyValues方法,用来实现bean的装配,这就相当于策略模式中的抽象策略。

AutowireCapableBeanFactory中继承了AbstractBeanFactory,重写了applyPropertyValues方法,实现了自动装配逻辑,这就相当于策略模式中的具体策略

ClassPathXmlApplicationContext中,使用AutowireCapableBeanFactory构造父类AbstractApplicationContext,的AbstractBeanFactory,在父类中使用了AbstractBeanFactory.applyPropertyValues方法,算是策略模式中的环境角色

单例模式

getBean方法,如果bean为null就创建bean,不为null就直接从beanDefinitionMap中取,实现了bean单例

模板方法模式

在AbstractBeanFactory.getBean中,创建bean的步骤分为了,实例化bean、装配、生成代理类等,将装配定义为抽象模板方法,定义了算法骨架,而子类AutowireCapableBeanFactory实现了具体模板方法。

外观模式

ClassPathXmlApplicationContext,将xmlBeanDefinitionReader、beanFactory等等封装,实现了路径加载资源,就构建了一个外观角色,用户只要使用ClassPathXmlApplicationContext,就可以根据路径加载资源并创建bean等操作。

 

你可能感兴趣的:(模拟SpringIOC准备)