spring 源码解读与设计详解:2 BeanFactory
在spring的官网中我们看到,spring的产品已经发展的非常壮大,然而很多产品对于很多公司来讲用的非常少,甚至用不到。因此本系列的源码解读也不会涉及全部的spring的产品。而是只对spring的核心功能IoC和AOP进行解释。
所谓源码解读,解读的是什么?实际上源码解读读的更多的是源码的注释,因为一个类的作用、一个接口或者一个方法的作用,我们往往是要根据注释才知道,这也是为什么在代码规范中,注释是一个非常重要的模块的原因。
参考:
Spring源码分析——BeanFactory体系之接口详细分析
源文档 <http://www.2cto.com/kf/201410/345534.html>
spring最核心的也就是IOC了。那么IoC最核心的一个接口,当属BeanFactory。BeanFactory的作用类似于java中的Object类。
1、首先看一下BeanFactory在spring中的位置:(项目中引入的都是spring-framework中的jar)
2、我们再看一下BeanFactory的类结构。常用的ApplicationContext就是继承于BeanFactory。
PS:由于层级较高,截图中的所有类并没有全部展开
(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的类体系结构看似繁杂混乱,实际上由上而下井井有条,非常容易理解。
3、BeanFactory的类的作用,看注释,其中的译文是本人自己翻译的,水平极度有限,望高手不吝指教,通过对BeanFactory的注释,我们也就理解了BeanFactory的作用
/**
* The root interface for accessing a Springbean container.
* This is the basic client view of a beancontainer;
* further interfaces such as {@linkListableBeanFactory} and
* {@linkorg.springframework.beans.factory.config.ConfigurableBeanFactory}
* are available for specific purposes.
*
* 译:访问spring bean 容器的基础(根)接口
* 这是查看bean容器的基础客户端
*更多的接口,例如ListableBeanFactory或者ConfigurableBeanFactory可以满足特殊的需要
*
* <p>This interface is implemented byobjects that hold a number of bean definitions,
* each uniquely identified by a String name.Depending on the bean definition,
* the factory will return either anindependent instance of a contained object
* (the Prototype design pattern), or a singleshared instance (a superior
* alternative to the Singleton design pattern,in which the instance is a
* singleton in the scope of the factory).Which type of instance will be returned
* depends on the bean factory configuration:the API is the same. Since Spring
* 2.0, further scopes are available dependingon the concrete application
* context (e.g. "request" and"session" scopes in a web environment).
*
*译:这个接口被一系列的bean定义的对象实现,每一个对象都有唯一确定字符串名字。根据bean定义,
*工厂会返回一个独立的对象的实例(prototype设计模式),或者返回一个单例共享的实例(更好的单例设计模式是在工厂内单例)
* 返回那种类型的对象的实例取决于bean工厂的配置:API是一样的。
*从spring2.0开始,根据具体的应用程序上下文可以选择更多的范围(scope,实例的类型),
* 比如在web环境中可以用request、session等
*
* <p>The point of this approach is thatthe BeanFactory is a central registry
* of application components, and centralizesconfiguration of application
* components (no more do individual objectsneed to read properties files,
* for example). See chapters 4 and 11 of"Expert One-on-One J2EE Design and
* Development" for a discussion of thebenefits of this approach.
*
*译:这种方式的关键是使BeanFactory成为应用程序组件的注册中心和配置中心(例如,单个对象不再需要读取属性文件)
* 对于这种方式的好处的讨论,
* 可以参考"Expert One-on-One J2EE Design andDevelopment"这本书的第4章和11章,
*
* <p>Note that it is generally better torely on Dependency Injection
* ("push" configuration) toconfigure application objects through setters
* or constructors, rather than use any form of"pull" configuration like a
* BeanFactory lookup. Spring‘s DependencyInjection functionality is
* implemented using this BeanFactory interfaceand its subinterfaces.
*
*译:注意,通常推荐使用setter方法或者构造方法的方式去配置应用程序对象的依赖注入(“push”,推的配置),
* 而不是拉 pull的方式,比如BeanFactory的查找。
* spring的依赖注入功能是通过BeanFactory接口和它的子接口的实现类实现的。
*
* <p>Normally a BeanFactory will loadbean definitions stored in a configuration
* source (such as an XML document), and usethe {@code org.springframework.beans}
* package to configure the beans. However, animplementation could simply return
* Java objects it creates as necessarydirectly in Java code. There are no
* constraints on how the definitions could bestored: LDAP, RDBMS, XML,
* properties file, etc. Implementations areencouraged to support references
* amongst beans (Dependency Injection).
*
* 译:通常BeanFactory加载存储在配置源(例如一个xml文档)中的bean定义,
* 并且使用org.springframework.beans这个包去配置这些beans。
* 然而,一个实现可以简单的返回Java对象,它创建必要的java代码。
*对于bean定义如何存储没有限制:例如,Ldap、rdbms、xml、properties files。
* 实现方式鼓励使用bean的引用(依赖注入)
*
* <p>In contrast to the methods in{@link ListableBeanFactory}, all of the
* operations in this interface will also checkparent factories if this is a
* {@link HierarchicalBeanFactory}. If a beanis not found in this factory instance,
* the immediate parent factory will be asked.Beans in this factory instance
* are supposed to override beans of the samename in any parent factory.
*
*译:与ListableBeanFactory接口作对比,HierarchicalBeanFactory的
* 接口中的所有操作会检查福工厂。
* 如果一个bean在当前的工厂实例中没有被找到,那么会立即访问它的父工厂。
* 在该工厂实例中的所有bean会重写它任何一个父工厂中相同名字的bean
*
*
* <p>Bean factory implementations shouldsupport the standard bean lifecycle interfaces
* as far as possible. The full set ofinitialization methods and their standard order is:<br>
* 1. BeanNameAware‘s {@codesetBeanName}<br>
* 2. BeanClassLoaderAware‘s {@codesetBeanClassLoader}<br>
* 3. BeanFactoryAware‘s {@codesetBeanFactory}<br>
* 4. ResourceLoaderAware‘s {@codesetResourceLoader}
* (only applicable when running in anapplication context)<br>
* 5. ApplicationEventPublisherAware‘s {@codesetApplicationEventPublisher}
* (only applicable when running in anapplication context)<br>
* 6. MessageSourceAware‘s {@codesetMessageSource}
* (only applicable when running in anapplication context)<br>
* 7. ApplicationContextAware‘s {@codesetApplicationContext}
* (only applicable when running in anapplication context)<br>
* 8. ServletContextAware‘s {@codesetServletContext}
* (only applicable when running in a webapplication context)<br>
* 9. {@code postProcessBeforeInitialization}methods of BeanPostProcessors<br>
* 10. InitializingBean‘s {@codeafterPropertiesSet}<br>
* 11. a custom init-methoddefinition<br>
* 12. {@code postProcessAfterInitialization}methods of BeanPostProcessors
*
* <p>On shutdown of a bean factory, thefollowing lifecycle methods apply:<br>
* 1. DisposableBean‘s {@codedestroy}<br>
* 2. a custom destroy-method definition
*
* 译:当一个bean工厂停止时,会调用下面的生命周期相关方法:
* 1. 销毁bean的方法(destroy)
* 2. 用户自定义的destory方法
*
4、BeanFactory的方法:
(1)、5个获取实例的方法。getBean的重载方法。
(2)、4个判断的方法。判断是否存在,是否为单例、原型,名称类型是否匹配。
(3)、1个获取类型的方法、一个获取别名的方法。根据名称获取类型、根据名称获取别名。一目了然!
(4)、1个变量
/**
* Used to dereference a {@link FactoryBean}instance and distinguish it from
* beans <i>created</i> by theFactoryBean. For example, if the bean named
* {@code myJndiObject} is a FactoryBean,getting {@code &myJndiObject}
* will return the factory, not the instancereturned by the factory.
*
*译:用于去掉factorybean实例引用以及区分被factoryb创建bean。例如,如果一个名为myJndiObject的FactoryBean,
* getting&myJndiObject,返回的是这个factory,而不是被这个factory创建的实例
*/
StringFACTORY_BEAN_PREFIX = "&";
总结:
这11个方法,很明显,这是一个典型的工厂模式的工厂接口。
本篇文章到此结束,关于更多的源码解析,以及实现原理等,请看后续文章更新。
个人能力及其有限,望高手不吝指教,如博文中有问题,欢迎读者留言指正。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。