Spring IOC-BeanFactory的继承体系结构
2015-07-01 22:41
701 查看
本文主要介绍BeanFactory以及它的各种继承层级的接口、抽象类及实现类,因为内容很多,所以这里不介绍ApplicationContext继承体系下的类(虽然ApplicationContext本质上也是BeanFactory,但是毕竟这这是我们平时接触最多的两种类别,所以分开说)。
关于ApplicationContext继承体系结构在《Spring IOC-ApplicationContext的继承体系结构》一文分享说明。
BeanFactory其实就是Spring的IOC容器,当然了Spring为我们准备了许多种IOC容器来使用,这样可以方便我们从不同的层面,不同的资源位置,不同的形式的定义信息来建立我们需要的IoC容器。
在鄙人博客的不同的博文中其实都提到了Spring的一个设计理念,就是接口-抽象类-实现类的体系结构,这里多说几句为什么这么设计,熟悉设计模式的人都知道,这样的目的是为了提高软件的可维护性、可扩展性、强复用性。说的文雅一点就是使代码满足“对修改关闭、对扩展开放”、“里氏代换”原则 、“依赖倒转”原则、“接口隔离”原则、“合成\聚合复用”原则。如果项了解这几个原则可以百度下,这里不详细介绍。
废话不多说,直接上代码来看下BeanFactory的继承道理多屌。
先贴张图,由于是手工画的,很粗糙,大家大致看下知道下面介绍的类大概在继承体系的哪个位置。
首先看BeanFactory接口中定义的方法:
然后在看BeanFactory 的直接继承接口(二级接口),有HierarchicalBeanFactory、AutowireCapableBeanFactory和ListableBeanFactory看这三个类代码:
HierarchicalBeanFactory
作用:是为了实现bean工厂的层级关系提供支持,其中声明两个方法:
AutowireCapableBeanFactory
作用:提供自动装配bean能力的功能支持,声明方法如下:(这个接口中所有声明的方法都是在默认的实现实在AbstractAutowireCapableBeanFactory类中默认实现)
ListableBeanFactory
作用:可以枚举所有的bean实例,是为了使客户端访问工厂中的bean而设计的,主要方法(这些方法顾名思义,所有的方法实现在StaticListableBeanFactory、AbstractApplicationContext和DefaultListableBeanFactory中):
下面我们介绍BeanFactory 的三级接口,看继承关系图知道是ConfigurableBeanFactory和ConfigurableListableBeanFactory。
ConfigurableBeanFactory
作用: 实现可配置的bean的环境功能,这个接口继承自HierarchicalBeanFactory所以支持层级关系的工厂,和SingletonBeanRegistry所以肯定支持单例工厂行为,看主要方法代码(在AbstractBeanFactory类中默认实现):
ConfigurableListableBeanFactory
作用:提供可配置的、可访问的功能,接口中的方法在在DefaultListableBeanFactory默认实现默认实现。
上面是接口的继承体系和说明,下面来介绍接口下抽象类的代码,在上面的介绍中我们知道就两个抽象类AbstractAutowireCapableBeanFactory和AbstractBeanFactory,先看继承关系:
可以知道AbstractAutowireCapableBeanFactory 是AbstractBeanFactory 类的子类。通过上面的接口和抽象类的介绍我们将研究的重点转到转到这两个抽象类中。
这里我们主要看bean工厂是怎么将xml中的定义信息转换为互相依赖的bean定义或者初始化为实体对象。
先看在继承体系偏上的类AbstractBeanFactory ,这个类最重要的是对BeanFactory中getBean()的实现,直接看实现的代码:
在看doGetBean()方法代码:
可以上面是分为三种情况得到bean的,单例的、多例的、Scope的。但是所有的情况最终都定位到一个方法——createBean(beanName, mbd, args),这个方法在AbstractBeanFactory 是抽象的
好的,代码定位到doCreateBean(beanName, mbd, args)方法:
代码定位到createBeanInstance(beanName, mbd, args)
再定位代码到populateBean(beanName, mbd, instanceWrapper):
最后是applyPropertyValues(beanName, mbd, bw, pvs)
这里补充一下BeanWrapperImpl类中设置属性依赖的代码实现:
至此bean的如何初始化和如何进行依赖注入就已经研究代码完毕。
下面也是最后我们看一下这个继承体系中具体类XmlBeanFactory、DefaultListableBeanFactory的实现代码:
XmlBeanFactory
关于XmlBeanFactory加载xml,会在Spring IOC-XmlBeanFactory如何加载xml及如何存储转换后的信息一文介绍。
DefaultListableBeanFactory
是XmlBeanFactory的父类,也就是而你看下文章最前面的继承图,你会发现DefaultListableBeanFactory拥有这个继承体系中的所有功能。
那么除了继承父类的功能方法外,它独特的功能在于对ConfigurableListableBeanFactory和ListableBeanFactory接口的实现。
关于ApplicationContext继承体系结构在《Spring IOC-ApplicationContext的继承体系结构》一文分享说明。
BeanFactory其实就是Spring的IOC容器,当然了Spring为我们准备了许多种IOC容器来使用,这样可以方便我们从不同的层面,不同的资源位置,不同的形式的定义信息来建立我们需要的IoC容器。
在鄙人博客的不同的博文中其实都提到了Spring的一个设计理念,就是接口-抽象类-实现类的体系结构,这里多说几句为什么这么设计,熟悉设计模式的人都知道,这样的目的是为了提高软件的可维护性、可扩展性、强复用性。说的文雅一点就是使代码满足“对修改关闭、对扩展开放”、“里氏代换”原则 、“依赖倒转”原则、“接口隔离”原则、“合成\聚合复用”原则。如果项了解这几个原则可以百度下,这里不详细介绍。
废话不多说,直接上代码来看下BeanFactory的继承道理多屌。
先贴张图,由于是手工画的,很粗糙,大家大致看下知道下面介绍的类大概在继承体系的哪个位置。
首先看BeanFactory接口中定义的方法:
public interface BeanFactory { //这里是对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象 String FACTORY_BEAN_PREFIX = "&"; //这里根据bean的名字,在IOC容器中得到bean实例,这个IOC容器就是一个大的抽象工厂。 Object getBean(String name) throws BeansException; //这里根据bean的名字和Class类型来得到bean实例,和上面的方法不同在于它会抛出异常:如果根据名字取得的bean实例的Class类型和需要的不同的话。 <T> T getBean(String name, Class<T> requiredType); <T> T getBean(Class<T> requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; //这里提供对bean的检索,看看是否在IOC容器有这个名字的bean boolean containsBean(String name); //这里根据bean名字得到bean实例,并同时判断这个bean是不是单件 boolean isSingleton(String name) throws NoSuchBeanDefinitionException; //这里根据bean名字得到bean实例,并同时判断这个bean是不是原型 boolean isPrototype(String name) throws NoSuchBeanDefinitionException; //这里对得到bean实例的Class类型 Class<?> getType(String name) throws NoSuchBeanDefinitionException; //这里得到bean的别名,如果根据别名检索,那么其原名也会被检索出来 String[] getAliases(String name);
然后在看BeanFactory 的直接继承接口(二级接口),有HierarchicalBeanFactory、AutowireCapableBeanFactory和ListableBeanFactory看这三个类代码:
HierarchicalBeanFactory
作用:是为了实现bean工厂的层级关系提供支持,其中声明两个方法:
//得到父工厂 BeanFactory getParentBeanFactory(); //在本地工厂中有没有给定名称的bean,不包括继承的工厂 boolean containsLocalBean(String name);
AutowireCapableBeanFactory
作用:提供自动装配bean能力的功能支持,声明方法如下:(这个接口中所有声明的方法都是在默认的实现实在AbstractAutowireCapableBeanFactory类中默认实现)
//用个给定的class类型制造一个完整的bean <T> T createBean(Class<T> beanClass) throws BeansException; //bean初始化完成之后执行回调函数和后处理器, void autowireBean(Object existingBean) throws BeansException; // 自动注入和设置bean的属性、执行factory回调函数比如setBeanName和setBeanFactory和执行bean的所有的后处理器 Object configureBean(Object existingBean, String beanName) throws BeansException; //调用bean的init方法,这个方法是客户配置的,在bean实例化之后调用 Object initializeBean(Object existingBean, String beanName) throws BeansException; //初始化完成之后应用后处理器 Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) //应用前处理器 Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName);
ListableBeanFactory
作用:可以枚举所有的bean实例,是为了使客户端访问工厂中的bean而设计的,主要方法(这些方法顾名思义,所有的方法实现在StaticListableBeanFactory、AbstractApplicationContext和DefaultListableBeanFactory中):
//是否含有给定的名称的bean boolean containsBeanDefinition(String beanName); int getBeanDefinitionCount(); //得到工厂所有的bean的名称数组 String[] getBeanDefinitionNames(); String[] getBeanNamesForType(Class<?> type); //根据给定的类型得到和相应的策略得到所有的bean名称数组 String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit); //根据给定过的类型得到所有该类型的bean,返回的结果是一个Map<bean名称,bean对象>的形式 <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException; //得到给定名称的bean上的给定注解类型的注解对象 <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);
下面我们介绍BeanFactory 的三级接口,看继承关系图知道是ConfigurableBeanFactory和ConfigurableListableBeanFactory。
ConfigurableBeanFactory
作用: 实现可配置的bean的环境功能,这个接口继承自HierarchicalBeanFactory所以支持层级关系的工厂,和SingletonBeanRegistry所以肯定支持单例工厂行为,看主要方法代码(在AbstractBeanFactory类中默认实现):
void setConversionService(ConversionService conversionService); void setTypeConverter(TypeConverter typeConverter); //支持自定义bean的作用范围,可以理解为单例和多例之外的 void registerScope(String scopeName, Scope scope); //归并的将给定的name的bean的定义 BeanDefinition getMergedBeanDefinition(String beanName); //添加处理器 void addBeanPostProcessor(BeanPostProcessor beanPostProcessor); //下面是3个destory方法 void destroyBean(String beanName, Object beanInstance); void destroyScopedBean(String beanName); //只能销毁所有单例的bean,因为多例的是不归Spring控制的,是由客户端控制的 void destroySingletons();
ConfigurableListableBeanFactory
作用:提供可配置的、可访问的功能,接口中的方法在在DefaultListableBeanFactory默认实现默认实现。
public interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory { //冻住之后bean定义就不能在被修改和进行任何的后处理器规定的操作 void freezeConfiguration(); //确保所有的单例bean都实例化 void preInstantiateSingletons() throws BeansException; // BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; //判断当前的bean是不是作为其它bean的依赖注入的 boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor);
上面是接口的继承体系和说明,下面来介绍接口下抽象类的代码,在上面的介绍中我们知道就两个抽象类AbstractAutowireCapableBeanFactory和AbstractBeanFactory,先看继承关系:
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
可以知道AbstractAutowireCapableBeanFactory 是AbstractBeanFactory 类的子类。通过上面的接口和抽象类的介绍我们将研究的重点转到转到这两个抽象类中。
这里我们主要看bean工厂是怎么将xml中的定义信息转换为互相依赖的bean定义或者初始化为实体对象。
先看在继承体系偏上的类AbstractBeanFactory ,这个类最重要的是对BeanFactory中getBean()的实现,直接看实现的代码:
……………… public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException { return doGetBean(name, requiredType, args, false); }
在看doGetBean()方法代码:
……………… //首先从单例工厂得到有没有 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } //不是但单例的 else { //看是不是在父BeanFactory ,因为实现了HierarchicalBeanFactory接口 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { return parentBeanFactory.getBean(nameToLookup, requiredType); } …………………… if (mbd.isSingleton()) {//单例的 //用回调的形式建造bean并且放入单例工厂 sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } …………………… //多例的 else if (mbd.isPrototype()) { Object prototypeInstance = null; beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); ……………… else {//没有明确是单例的还是不是,有自己的作用域scope String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException { return createBean(beanName, mbd, args); ……………………
可以上面是分为三种情况得到bean的,单例的、多例的、Scope的。但是所有的情况最终都定位到一个方法——createBean(beanName, mbd, args),这个方法在AbstractBeanFactory 是抽象的
protected abstract Object createBean(,很明显,只能在子类中实现,自然就要看AbstractAutowireCapableBeanFactory 中的建造bean的createBean()代码:
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { ……………… //如果没有找到这个name的class类型是会抛出异常的 resolveBeanClass(mbd, beanName); //判断在xml中定义的overrides方法存在 mbd.prepareMethodOverrides(); ……………… //用bean的前处理器去实例化 Object bean = resolveBeforeInstantiation(beanName, mbd); ……………… Object beanInstance = doCreateBean(beanName, mbd, args); ………………
好的,代码定位到doCreateBean(beanName, mbd, args)方法:
//逐渐的构造一个bean,分别用factory method, and autowiring a constructor.去构造,这些都是在xml中配置的。 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { ……………… instanceWrapper = createBeanInstance(beanName, mbd, args); ……………… //构造bean并且注入依赖所有bean的属性值 Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { //调用配置的init方法 exposedObject = initializeBean(beanName, exposedObject, mbd); } }
代码定位到createBeanInstance(beanName, mbd, args)
//用 factory method, constructor autowiring, or simple instantiation.三种方法去实例化一个bean protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { ……………… //用getFactoryMethodName去实例化一个 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } ……………… //用构造函数 if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); }else { //用默认的构造函数得到 return instantiateBean(beanName, mbd); } ……………… }
再定位代码到populateBean(beanName, mbd, instanceWrapper):
//主要是bean中的成员变量的初始化和注入,《依赖的注入》 protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) { …………………… if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } …………………… //将属性的引用和具体的对象结合起来,用到了java的反射机制 applyPropertyValues(beanName, mbd, bw, pvs); }
最后是applyPropertyValues(beanName, mbd, bw, pvs)
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { try { //调用BeanWrapper类的方法 bw.setPropertyValues(new MutablePropertyValues(deepCopy)); }
这里补充一下BeanWrapperImpl类中设置属性依赖的代码实现:
……………… //如果有key属性配置,证明是array list 或者map if (tokens.keys != null) { if (propValue.getClass().isArray()) { else if (propValue instanceof List) { else if (propValue instanceof Map) { } //普通的属性设置 else{ ……………… writeMethod.setAccessible(true); writeMethod.invoke(object, value); } ………………
至此bean的如何初始化和如何进行依赖注入就已经研究代码完毕。
下面也是最后我们看一下这个继承体系中具体类XmlBeanFactory、DefaultListableBeanFactory的实现代码:
XmlBeanFactory
//这个类的实现很简单,只是委托XmlBeanDefinitionReader进行xml的读取和配置信息的加载 public class XmlBeanFactory extends DefaultListableBeanFactory { private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this); // 构造的时候就进行xml文件的解析 public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException { super(parentBeanFactory); this.reader.loadBeanDefinitions(resource); } }
关于XmlBeanFactory加载xml,会在Spring IOC-XmlBeanFactory如何加载xml及如何存储转换后的信息一文介绍。
DefaultListableBeanFactory
是XmlBeanFactory的父类,也就是而你看下文章最前面的继承图,你会发现DefaultListableBeanFactory拥有这个继承体系中的所有功能。
那么除了继承父类的功能方法外,它独特的功能在于对ConfigurableListableBeanFactory和ListableBeanFactory接口的实现。
相关文章推荐
- Java文件操作
- Spring的事务管理的几种方法
- Struts2开发遇到的问题之多文件上传
- Java内部类详解
- 2015070103 - EffactiveJava笔记 - 第47条 了解和使用类库(2)
- 排序算法之归并排序Java版
- 排序算法之快速排序Java版
- Java每日编程day2
- Java基础之简单内存管理
- 使用java的Calendar对象获得当前日期的上几个度开始、结束时间
- 排序算法之冒泡排序Java版
- Java面向对象之类
- 2015070102 - EffactiveJava笔记 - 第47条 了解和使用类库(1)
- java打包
- JAVA集合之——Comparable和Comparator
- MyBatis数据持久化(十)与Spring4整合
- MyBatis数据持久化(十)与Spring4整合
- SpringMVC+Spring+Mybatis整合
- MyBatis数据持久化(十)与Spring4整合
- myEclipse6.5注册码生成