spring 源码解读与设计详解:2 BeanFactory

spring的官网中我们看到,spring的产品已经发展的非常壮大,然而很多产品对于很多公司来讲用的非常少,甚至用不到。因此本系列的源码解读也不会涉及全部的spring的产品。而是只对spring的核心功能IoCAOP进行解释。

      所谓源码解读,解读的是什么?实际上源码解读读的更多的是源码的注释,因为一个类的作用、一个接口或者一个方法的作用,我们往往是要根据注释才知道,这也是为什么在代码规范中,注释是一个非常重要的模块的原因。

 

参考:

Spring源码分析——BeanFactory体系之接口详细分析

 

源文档 <http://www.2cto.com/kf/201410/345534.html> 

 

        spring最核心的也就是IOC了。那么IoC最核心的一个接口,当属BeanFactoryBeanFactory的作用类似于java中的Object类。

        1、首先看一下BeanFactoryspring中的位置:(项目中引入的都是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的类体系结构看似繁杂混乱,实际上由上而下井井有条,非常容易理解。


3BeanFactory的类的作用,看注释,其中的译文是本人自己翻译的,水平极度有限,望高手不吝指教,通过对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方法

 *

     

 4BeanFactory的方法:

技术分享


  (15个获取实例的方法。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个方法,很明显,这是一个典型的工厂模式的工厂接口。


本篇文章到此结束,关于更多的源码解析,以及实现原理等,请看后续文章更新。

个人能力及其有限,望高手不吝指教,如博文中有问题,欢迎读者留言指正。


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。