BeanDefinition是Bean的元数据,它定义了Bean的Class类型、name、bean的属性集合、bean的实例。
Bean在IOC容器中的定义,IOC容器可以根据这个来定义来生成实例。以BeanDefinition类为核心散发出的几个类,都是用于解决Bean的基本定义问题,包括他的类型、属性赋值等
它封装了Bean的属性,它有两个成员变量:String name,Object value。对应着Spring的XML配置文件中的Property中的name和value:
如果value是ref时,要先解析,转换成BeanReference放入value
用于标识property标签的ref属性里的对象。
BeanPostProcessor接口用于bean定义初始化时的嵌入操作,如postProcessorAfterInitialization、postProcessorBeforeInitialization方法,解决在Ioc容器如何植入Aop的问题
标识一个Ioc容器,以BeanFactory为接口的实体类,都用于解决Ioc容器在已经过去Bean的定义时,解决如何装配、获取实例的问题。
它有一个方法,getBean(name),通过name获取Bean实例
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处理程序。
setBeanFactory(beanFactory),实现该接口则有操作BeanFactory的能力,
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注入。
资源加载类,通过给定名称查找资源返回inputStream
解析BeanDefinition的接口,暴露加载bean的方法
locadBeanDefinitions(String location)根据地址加载bean的定义
BeanDefinitionReader接口的实现类,规范了BeanDefinitionReader的基本接口
Registry 键值存储的IOC容器(beanDefinitionMap)
ResourceLoader,资源加载类
AbstractBeanDefinitionReader的实现类,从XMl中读取bean的定义,实现了loadBeanDefinitions()方法
loadBeanDefinitions(),获取资源输入流,解析为Document,获取根
以ApplicationContext为接口的实现类,主要对Resource、BeanFactory进行了功能封装,解决根据地址获取资源通过IOC容器注册Bean定义并且实例化的问题。
ApplicationContext的抽象实现,定义了创建bean的一些操作,AbstractBeanFactory成员变量。
Refresh()实现BeanFactory的刷新,加载出bean的定义保存到BeanFactory中,并实例化,初始化。
loadBeanDefinitions,加载出Bean的定义到beanFactory中
registerBeanPostProcessors,加载bean的处理器,用beanFactory的getBeansForType获取实现BeanPostProcessor接口的类,注册到abstractBeanFactory维护的beanPostProcessor列表中去,在通过getBean方法调用initializeBean,初始化bean处理器
onRefresh,实例化所有bean
getBean,根据名字获取bean
从类路径加载资源,继承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等操作。