Spring的BeanFactory的继承体系堪称经典。这是众所周知的!作为java程序员,不能错过!
前面的博文分析了Spring的Resource资源类Resouce。今天开始分析Spring的IOC部分。众所周知,IOC是Spring框架最迷人的地方。它最重要的接口,就是BeanFactory了。BeanFactory有着庞大的继承、实现体系,有众多的子接口、实现类。本博文的目标就是抽丝剥茧,从源代码入手,分析Spring的实现和架构,从中进步。
在阅读的过程中,可以参照Spring文档来一起学习:Spring3.1.1文档
本人英文水平有限,部分翻译可能不恰当,欢迎指出!
一、BeanFactory的基本类体系结构(接口为主):
这是我画的BeanFactory基本的类体系结构,这里没有包括强大的applicationContext体系,ApplicationContext我准备放到下一篇再分析。
具体:
1、BeanFactory作为一个主接口不继承任何接口,暂且称为一级接口。
2、有3个子接口继承了它,进行功能上的增强。这3个子接口称为二级接口。
3、ConfigurableBeanFactory可以被称为三级接口,对二级接口HierarchicalBeanFactory进行了再次增强,它还继承了另一个外来的接口SingletonBeanRegistry
4、ConfigurableListableBeanFactory是一个更强大的接口,继承了上述的所有接口,无所不包,称为四级接口。
(这4级接口是BeanFactory的基本接口体系。继续,下面是继承关系的2个抽象类和2个实现类:)
5、AbstractBeanFactory作为一个抽象类,实现了三级接口ConfigurableBeanFactory大部分功能。
6、AbstractAutowireCapableBeanFactory同样是抽象类,继承自AbstractBeanFactory,并额外实现了二级接口AutowireCapableBeanFactory
7、DefaultListableBeanFactory继承自AbstractAutowireCapableBeanFactory,实现了最强大的四级接口ConfigurableListableBeanFactory,并实现了一个外来接口BeanDefinitionRegistry,它并非抽象类。
8、最后是最强大的xmlBeanFactory,继承自DefaultListableBeanFactory,重写了一些功能,使自己更强大。
总结:
BeanFactory的类体系结构看似繁杂混乱,实际上由上而下井井有条,非常容易理解。
二、IOC的始祖——BeanFactory
来看一下BeanFactory的源码,这么牛逼哄哄的接口就不折叠了吧:
package%20org.springframework.beans.factory;public%20interface%20BeanFactory%20{%20%20%20%20/**%20%20%20%20%20*%20用来引用一个实例,或把它和工厂产生的Bean区分开,就是说,如果一个FactoryBean的名字为a,那么,&a会得到那个Factory%20%20%20%20%20*/%20%20%20%20String%20FACTORY_BEAN_PREFIX%20=%20"&";%20%20%20%20/*%20%20%20%20%20*%20四个不同形式的getBean方法,获取实例%20%20%20%20%20*/%20%20%20%20Object%20getBean(String%20name)%20throws%20BeansException;%20%20%20%20<T>%20T%20getBean(String%20name,%20Class<T>%20requiredType)%20throws%20BeansException;%20%20%20%20<T>%20T%20getBean(Class<T>%20requiredType)%20throws%20BeansException;%20%20%20%20Object%20getBean(String%20name,%20Object...%20args)%20throws%20BeansException;%20%20%20%20boolean%20containsBean(String%20name);%20//%20是否存在%20%20%20%20boolean%20isSingleton(String%20name)%20throws%20NoSuchBeanDefinitionException;//%20是否为单实例%20%20%20%20boolean%20isPrototype(String%20name)%20throws%20NoSuchBeanDefinitionException;//%20是否为原型(多实例)%20%20%20%20boolean%20isTypeMatch(String%20name,%20Class<?>%20targetType)%20%20%20%20%20%20%20%20%20%20%20%20throws%20NoSuchBeanDefinitionException;//%20名称、类型是否匹配%20%20%20%20Class<?>%20getType(String%20name)%20throws%20NoSuchBeanDefinitionException;%20//%20获取类型%20%20%20%20String[]%20getAliases(String%20name);//%20根据实例的名字获取实例的别名}
具体:
1、4个获取实例的方法。getBean的重载方法。
2、4个判断的方法。判断是否存在,是否为单例、原型,名称类型是否匹配。
3、1个获取类型的方法、一个获取别名的方法。根据名称获取类型、根据名称获取别名。一目了然!
总结:
这10个方法,很明显,这是一个典型的工厂模式的工厂接口。
三、可将Bean逐一列出的工厂——ListableBeanFactory
源码:
public interface ListableBeanFactory extends BeanFactory { boolean containsBeanDefinition(String beanName); // 对于给定的名字是否含有BeanDefinition int getBeanDefinitionCount(); // 返回工厂的BeanDefinition总数 String[] getBeanDefinitionNames(); // 返回工厂中所有Bean的名字 String[] getBeanNamesForType(Class<?> type); // 返回对于指定类型Bean(包括子类)的所有名字 /* * 返回指定类型的名字 includeNonSingletons为false表示只取单例Bean,true则不是 * allowEagerInit为true表示立刻加载,false表示延迟加载。 注意:FactoryBeans都是立刻加载的。 */ String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit); <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException; // 根据类型(包括子类)返回指定Bean名和Bean的Map <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException; Map<String, Object> getBeansWithAnnotation( Class<? extends Annotation> annotationType) throws BeansException; // 根据注解类型,查找所有有这个注解的Bean名和Bean的Map <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);// 根据指定Bean名和注解类型查找指定的Bean}View Code
具体:
1、3个跟BeanDefinition有关的总体操作。包括BeanDefinition的总数、名字的集合、指定类型的名字的集合。
(这里指出,BeanDefinition是Spring中非常重要的一个类,每个BeanDefinition实例都包含一个类在Spring工厂中所有属性。)
2、2个getBeanNamesForType重载方法。根据指定类型(包括子类)获取其对应的所有Bean名字。
3、2个getBeansOfType重载方法。根据类型(包括子类)返回指定Bean名和Bean的Map。
4、2个跟注解查找有关的方法。根据注解类型,查找Bean名和Bean的Map。以及根据指定Bean名和注解类型查找指定的Bean。
总结:
正如这个工厂接口的名字所示,这个工厂接口最大的特点就是可以列出工厂可以生产的所有实例。当然,工厂并没有直接提供返回所有实例的方法,也没这个必要。它可以返回指定类型的所有的实例。而且你可以通过getBeanDefinitionNames()得到工厂所有bean的名字,然后根据这些名字得到所有的Bean。这个工厂接口扩展了BeanFactory的功能,作为上文指出的BeanFactory二级接口,有9个独有的方法,扩展了跟BeanDefinition的功能,提供了BeanDefinition、BeanName、注解有关的各种操作。它可以根据条件返回Bean的集合,这就是它名字的由来——ListableBeanFactory。
四、分层的Bean工厂——HierarchicalBeanFactory
源码:
public interface HierarchicalBeanFactory extends BeanFactory { BeanFactory getParentBeanFactory(); // 返回本Bean工厂的父工厂 boolean containsLocalBean(String name); // 本地工厂是否包含这个Bean}View Code
具体:
1、第一个方法返回本Bean工厂的父工厂。这个方法实现了工厂的分层。
2、第二个方法判断本地工厂是否包含这个Bean(忽略其他所有父工厂)。这也是分层思想的体现。
总结:这个工厂接口非常简单,实现了Bean工厂的分层。这个工厂接口也是继承自BeanFacotory,也是一个二级接口,相对于父接口,它只扩展了一个重要的功能——工厂分层。
五、自动装配的Bean工厂——AutowireCapableBeanFactory
源码:
public interface AutowireCapableBeanFactory extends BeanFactory { int AUTOWIRE_NO = 0; // 这个常量表明工厂没有自动装配的Bean int AUTOWIRE_BY_NAME = 1; //表明根据名称自动装配 int AUTOWIRE_BY_TYPE = 2; //表明根据类型自动装配 int AUTOWIRE_CONSTRUCTOR = 3; //表明根据构造方法快速装配 @Deprecated int AUTOWIRE_AUTODETECT = 4; //表明通过Bean的class的内部来自动装配(有没翻译错...)Spring3.0被弃用。 <T> T createBean(Class<T> beanClass) throws BeansException; // 根据指定Class创建一个全新的Bean实例 void autowireBean(Object existingBean) throws BeansException; // 给定对象,根据注释、后处理器等,进行自动装配 /* * 根据Bean名的BeanDefinition装配这个未加工的Object,执行回调和各种后处理器。 */ Object configureBean(Object existingBean, String beanName) throws BeansException; /* * 分解Bean在工厂中定义的这个指定的依赖descriptor */ Object resolveDependency(DependencyDescriptor descriptor, String beanName) throws BeansException; /* * 根据给定的类型和指定的装配策略,创建一个新的Bean实例 */ Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; /* * 与上面类似,不过稍有不同。 */ Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; /* * 根据名称或类型自动装配 */ void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) throws BeansException; /* * 也是自动装配 */ void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException; /* * 初始化一个Bean... */ Object initializeBean(Object existingBean, String beanName) throws BeansException; /* * 初始化之前执行BeanPostProcessors */ Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException; /* * 初始化之后执行BeanPostProcessors */ Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException; /* * 分解指定的依赖 */ Object resolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;}View Code
具体:
1、总共5个静态不可变常量来指明装配策略,其中一个常量被Spring3.0废弃、一个常量表示没有自动装配,另外3个常量指明不同的装配策略——根据名称、根据类型、根据构造方法。
2、8个跟自动装配有关的方法,实在是繁杂,具体的意义我们研究类的时候再分辨吧。
3、2个执行BeanPostProcessors的方法。
4、2个分解指定依赖的方法
总结:这个工厂接口继承自BeanFacotory,它扩展了自动装配的功能,根据类定义BeanDefinition装配Bean、执行前、后处理器等。
六、复杂的配置Bean工厂——ConfigurableBeanFactory
源码:
新闻热点
疑难解答