`
wang4674890
  • 浏览: 87572 次
  • 性别: Icon_minigender_2
  • 来自: 厦门
社区版块
存档分类
最新评论

spring源代码分析(2)--BeanFactory

 
阅读更多

我们首先来看下BeanFacroty接口

 

  1. package org.springframework.beans.factory;
  2. import org.springframework.beans.BeansException;
  3. public interface BeanFactory {
  4.     
  5.     String FACTORY_BEAN_PREFIX = "&";
  6.     Object getBean(String name) throws BeansException;
  7.     Object getBean(String name, Class requiredType) throws BeansException;
  8.     
  9.     boolean containsBean(String name);
  10.     String[] getAliases(String name) throws NoSuchBeanDefinitionException;
  11. }


可以看出,BeanFactory定义了Factory的基本方法,他能够生成Bean以及辨别Bean是否包含在factory中,以及从一个Bean的名字的到其别名;

  1. package org.springframework.beans.factory;
  2. public interface HierarchicalBeanFactory extends BeanFactory {
  3.     
  4.     BeanFactory getParentBeanFactory();
  5.     boolean containsLocalBean(String name);
  6. }

HierarchicalBeanFactory在beanFactory的基础上,提供了BeanFactory能够集成父容器的功能,从而形成了工厂链;

  1. public interface ConfigurableBeanFactory extends HierarchicalBeanFactory {
  2.     void setParentBeanFactory(BeanFactory parentBeanFactory);
  3.     
  4.     void registerCustomEditor(Class requiredType, PropertyEditor propertyEditor);
  5.     
  6.     void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
  7.     
  8.     int getBeanPostProcessorCount();
  9.     
  10.     void registerAlias(String beanName, String alias) throws BeansException;
  11.     
  12.     void registerSingleton(String beanName, Object singletonObject) throws BeansException;
  13.     
  14.     boolean containsSingleton(String beanName);
  15.     
  16.     void destroySingletons();
  17. }

ConfigurableBeanFactory有继承了HierarchicalBeanFactory 接口,在HierarchicalBeanFactory 接口的基础上,有实现了BeanFactory的一些可配置功能,比如说增加VBeanPostProcessor,注册别名,注册单列等等;

  1. public interface ListableBeanFactory extends BeanFactory {
  2.     
  3.     boolean containsBeanDefinition(String beanName);
  4.     
  5.     int getBeanDefinitionCount();
  6.     
  7.     String[] getBeanDefinitionNames();
  8.     
  9.     
  10.     Map getBeansOfType(Class type, boolean includePrototypes, boolean includeFactoryBeans)
  11.         throws BeansException;
  12. }

而ListableBeanFactory能够列出此工厂中的BeanDifinition的信息;一个BeanDifinition就是一个Bean,他不仅包含了Bean对象,并且他里面每一个配置文件就是其的一个属性,比如lazy-init,dependcy-check等等;

在这里,我们可以先来看看BeanDifinition;

可见,在接口设计的时候,先抽象出来接口,由于子类之间有共同的功能实现,那么,再次抽象出抽象类,尽量把相同的代码往上推,其次,最终实现;

ChildBeanDefinition和RootBeanDefinition分别表示两种BeanDefition类型,ChildBeanDefinition表示继承了别的Bean的配置信息的Bean元素,所以,他有一个直接的
    private final String parentName;

       public String getParentName() {
        return parentName;
    }

所以,在得到这个bean的时候,我们必须一层一层的往上组合merge才能得到完整的Bean的配置信息;

而大多数时候,我们使用RootBeanFactory,表示,这个Bean所具有的配置信息完全由他自己所定义;


弄清楚这个以后,我们从XmlBeanFactory来反推查看类结构;

在这里,我们可以看出类图结构错综复杂,很是繁琐,有些类在借口的实现过程中间出现了重复,我们来从上而下的分析这类图:

(1)AutowireCapableBeanFactory:实现了自动装配的功能,在此接口中,定义了几种自动装配的类型,比如:

  1.     int AUTOWIRE_BY_NAME = 1;
  2.     int AUTOWIRE_BY_TYPE = 2;
  3.     
  4.     int AUTOWIRE_CONSTRUCTOR = 3;
  5.     int AUTOWIRE_AUTODETECT = 4;

并且能够检查Bean自动装配的BeanPostProcessors的postProcessAfter/BeforeInitialization并且应用;

  1.     Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
  2.             throws BeansException;
  3.     Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
  4.             throws BeansException;

AbstractBeanFactory则是上述接口的 一个抽象实现,很多方法都在此方法中得到了实现;

首先是BeanFactory功能的实现;如:

  1. public Object getBean(String name, Class requiredType, Object[] args) throws BeansException {
  2.         String beanName = transformedBeanName(name);
  3.      //对名字进行了预处理,去掉了“&”
  4.         Object bean = null;
  5.         // Eagerly check singleton cache for manually registered singletons.
  6.         Object sharedInstance = null;
  7.         synchronized (this.singletonCache) {
  8.         //是否是共享的实例;若是,则从缓存中取出;
  9.             sharedInstance = this.singletonCache.get(beanName);
  10.         }
  11.         if (sharedInstance != null) {
  12.            //此例是否正在生成?
  13.             if (isSingletonCurrentlyInCreation(beanName)) {
  14.                 if (logger.isDebugEnabled()) {
  15.                     logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
  16.                             "' that is not fully initialized yet - a consequence of a circular reference");
  17.                 }
  18.             }
  19.             else {
  20.                 if (logger.isDebugEnabled()) {
  21.                     logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
  22.                 }
  23.             }
  24.             bean = getObjectForSharedInstance(name, sharedInstance);
  25.         }
  26.         else {
  27.             // Fail if we're already creating this singleton instance:
  28.             // We're assumably within a circular reference.
  29.             if (isSingletonCurrentlyInCreation(beanName)) {
  30.                 throw new BeanCurrentlyInCreationException(beanName);
  31.             }
  32.             // Check if bean definition exists in this factory.
  33.             if (getParentBeanFactory() != null && !containsBeanDefinition(beanName)) {
  34.                 // Not found -> check parent.
  35.                 if (getParentBeanFactory() instanceof AbstractBeanFactory) {
  36.                     // Delegation to parent with args only possible for AbstractBeanFactory.
  37.                     return ((AbstractBeanFactory) getParentBeanFactory()).getBean(name, requiredType, args);
  38.                 }
  39.                 else if (args == null) {
  40.                     // No args -> delegate to standard getBean method.
  41.                     //通过父容器来取得Bean
  42.                     return getParentBeanFactory().getBean(name, requiredType);
  43.                 }
  44.                 else {
  45.                     throw new NoSuchBeanDefinitionException(beanName,
  46.                             "Cannot delegate to parent BeanFactory because it does not supported passed-in arguments");
  47.                 }
  48.             }
  49.             //得到一个完整的BeanDefinition;
  50.             RootBeanDefinition mergedBeanDefinition = getMergedBeanDefinition(beanName, false);
  51.             checkMergedBeanDefinition(mergedBeanDefinition, beanName, requiredType, args);
  52.             // Create bean instance.
  53.             //如果是单例,那么就添加在单例map中去;
  54.             //在这里,你可以看成享元模式的一种灵活应用,
  55.             if (mergedBeanDefinition.isSingleton()) {
  56.                 synchronized (this.singletonCache) {
  57.                     // Re-check singleton cache within synchronized block.
  58.                     sharedInstance = this.singletonCache.get(beanName);
  59.                     if (sharedInstance == null) {
  60.                         if (logger.isDebugEnabled()) {
  61.                             logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
  62.                         }
  63.                         //标示一下,此实例Bean正在生成,以免Sington重复创建,变相达到线程安全;
  64.                         this.currentlyInCreation.add(beanName);
  65.                         try {
  66.                             sharedInstance = createBean(beanName, mergedBeanDefinition, args);
  67.                             addSingleton(beanName, sharedInstance);
  68.                         }
  69.                         catch (BeansException ex) {
  70.                             // Explicitly remove instance from singleton cache: It might have been put there
  71.                             // eagerly by the creation process, to allow for circular reference resolution.
  72.                             // Also remove any beans that received a temporary reference to the bean.
  73.                             destroyDisposableBean(beanName);
  74.                             throw ex;
  75.                         }
  76.                         finally {
  77.                             //beanDefinition生成完毕,从正在创建数组中移除
  78.                             this.currentlyInCreation.remove(beanName);
  79.                         }
  80.                     }
  81.                 }
  82.                 bean = getObjectForSharedInstance(name, sharedInstance);
  83.             }
  84.             else {
  85.                 //如果是原型Bean,,那么我们直接应用这个类型来生成一个实例
  86.                 bean = createBean(beanName, mergedBeanDefinition, args);
  87.             }
  88.         }
  89.         // Check if required type matches the type of the actual bean instance.
  90.         if (requiredType != null && !requiredType.isAssignableFrom(bean.getClass())) {
  91.             throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
  92.         }
  93.         return bean;
  94.     }


(2)HierarchicalBeanFactory的实现:

  1. public BeanFactory getParentBeanFactory() {
  2.         return parentBeanFactory;
  3.     }
  4.     public boolean containsLocalBean(String name) {
  5.         String beanName = transformedBeanName(name);
  6.         return (containsSingleton(beanName) || containsBeanDefinition(beanName));
  7.     }

判断一个Bean是否在本地配置;而不是在父工厂中生成;

我们可以抽取出mergeBeanDefinition来看看:

  1.     protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
  2.             throws BeanDefinitionStoreException {
  3.         //如果是根Bean.则返回,退出嵌套;
  4.         if (bd instanceof RootBeanDefinition) {
  5.             // Return root bean definition as-is.
  6.             return (RootBeanDefinition) bd;
  7.         }
  8.         else if (bd instanceof ChildBeanDefinition) {
  9.             // Child bean definition: needs to be merged with parent.
  10.             ChildBeanDefinition cbd = (ChildBeanDefinition) bd;
  11.             RootBeanDefinition pbd = null;
  12.             try {
  13.                 if (!beanName.equals(cbd.getParentName())) {
  14.                 //在这里进行了嵌套;
  15.                     pbd = getMergedBeanDefinition(cbd.getParentName(), true);
  16.                 }
  17.                 else {
  18.                     if (getParentBeanFactory() instanceof AbstractBeanFactory) {
  19.                         AbstractBeanFactory parentFactory = (AbstractBeanFactory) getParentBeanFactory();
  20.                         pbd = parentFactory.getMergedBeanDefinition(cbd.getParentName(), true);
  21.                     }
  22.                     else {
  23.                         throw new NoSuchBeanDefinitionException(cbd.getParentName(),
  24.                                 "Parent name '" + cbd.getParentName() + "' is equal to bean name '" + beanName +
  25.                                 "': cannot be resolved without an AbstractBeanFactory parent");
  26.                     }
  27.                 }
  28.             }
  29.             catch (NoSuchBeanDefinitionException ex) {
  30.                 throw new BeanDefinitionStoreException(cbd.getResourceDescription(), beanName,
  31.                         "Could not resolve parent bean definition '" + cbd.getParentName() + "'", ex);
  32.             }
  33.             // Deep copy with overridden values.
  34.             RootBeanDefinition rbd = new RootBeanDefinition(pbd);
  35.             rbd.overrideFrom(cbd);
  36.             // Validate merged definition: mainly to prepare method overrides.
  37.             try {
  38.                 rbd.validate();
  39.             }
  40.             catch (BeanDefinitionValidationException ex) {
  41.                 throw new BeanDefinitionStoreException(rbd.getResourceDescription(), beanName,
  42.                         "Validation of bean definition failed", ex);
  43.             }
  44.             return rbd;
  45.         }
  46.         else {
  47.             throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
  48.                     "Definition is neither a RootBeanDefinition nor a ChildBeanDefinition");
  49.         }
  50.     }
  • sharedInstance = createBean(beanName, mergedBeanDefinition, args);
  •                             addSingleton(beanName, sharedInstance);

 


这段代码大量的应用了模板模式:createBean是在AbstractAutowireCapableBeanFactory类中实现的:
protected Object createBean(String beanName, RootBeanDefinition mergedBeanDefinition, Object[] args)
            throws BeanCreationException {

        // Guarantee initialization of beans that the current one depends on.
        if (mergedBeanDefinition.getDependsOn() != null) {
            for (int i = 0; i < mergedBeanDefinition.getDependsOn().length; i++) {
             //将依赖的类加载进来;
                getBean(mergedBeanDefinition.getDependsOn()[i]);
            }
        }


bean = applyBeanPostProcessorsBeforeInstantiation(mergedBeanDefinition.getBeanClass(), beanName);
会为这个Bean生成一个代理,每次都会调用拦截的方法;
AbstractAutoProxyCreator:

public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
        if (isInfrastructureClass(beanClass, beanName)) {
            return null;
        }

        // Create proxy here if we have a custom TargetSource.
        // Suppresses unnecessary default instantiation of the target bean:
        // The TargetSource will handle target instances in a custom fashion.
        TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
        if (targetSource != null) {
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            //生成代理
            return createProxy(beanClass, beanName, specificInterceptors, targetSource);
        }

        return null;
    }


在createBean的代码中,我们可以看见这么一段:

            populateBean(beanName, mergedBeanDefinition, instanceWrapper);

            if (bean instanceof BeanNameAware) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Invoking setBeanName on BeanNameAware bean '" + beanName + "'");
                }
                ((BeanNameAware) bean).setBeanName(beanName);
            }

            if (bean instanceof BeanFactoryAware) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Invoking setBeanFactory on BeanFactoryAware bean '" + beanName + "'");
                }
                ((BeanFactoryAware) bean).setBeanFactory(this);
            }

            originalBean = bean;
            bean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
            invokeInitMethods(beanName, bean, mergedBeanDefinition);
            bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);

在这个的代码中,我们可以清晰的看见Bean被实例化所要经过的一些过程;其中包括处理回调接口,调用init方法以及拦截器等等;

其次:
在最终的XmlBeanDefinition中:

public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
        super(parentBeanFactory);
        this.reader.loadBeanDefinitions(resource);
    }

这个Reader.load()实际上是一个XML解析器,他的功能是把xml配置文件转换成为BeanDefinition存储到BeanFactory的
BeanDefinition map中去;

BeanFactory的类图结构,大量的采用模板模式,在顶级的抽象类中间约定了算法的实际流程,而把算法的具体实现方式等等推到了子类实现,从而可以扩展出多个功能的工厂

 

 

分享到:
评论

相关推荐

    spring源代码解析

    代码解析2,部分摘抄 简单的说,在web容器中,通过ServletContext为Spring的IOC容器提供宿主环境,对应的建立起一个IOC容器的体系。其中,首先需要建立的是根上下文,这个上下文持有的对象可以有业务对象,数据存取...

    spring-04-源代码.rar

    使用Spring的IOC完成保存客户的操作: 。 案例需求 相关知识点 案例代码. Spring 整合 WEB 项目 引入 spring-web.jar 包: Spring 中的工厂(容器): BeanFactory(过时): Spring 配置文件中提示的配置

    spring-02-源代码.rar

    使用Spring的IOC完成保存客户的操作: 。 案例需求 相关知识点 案例代码. Spring 整合 WEB 项目 引入 spring-web.jar 包: Spring 中的工厂(容器): BeanFactory(过时): Spring 配置文件中提示的配置

    spring-01-源代码.rar

    使用Spring的IOC完成保存客户的操作: 。 案例需求 相关知识点 案例代码. Spring 整合 WEB 项目 引入 spring-web.jar 包: Spring 中的工厂(容器): BeanFactory(过时): Spring 配置文件中提示的配置

    spring源码分析

    在认真学习Rod.Johnson的三部曲之一:&lt;&lt;Professional Java Development with the spring framework&gt;&gt;,顺便也看了看源代码想知道 个究竟,抛砖引玉,有兴趣的同志一起讨论研究吧! 以下内容引自博客:...

    spring源码剖析

    在认真学习Rod.Johnson的三部曲之一:&lt;&lt;Professional Java Development with the spring framework&gt;&gt;,顺便也看了看源代码想知道 个究竟,抛砖引玉,有兴趣的同志一起讨论研究吧! 以下内容引自博客:...

    Spring中文帮助文档

    3.8.1. BeanFactory 还是 ApplicationContext? 3.8.2. 利用MessageSource实现国际化 3.8.3. 事件 3.8.4. 底层资源的访问 3.8.5. ApplicationContext在WEB应用中的实例化 3.9. 粘合代码和可怕的singleton 3.10....

    Spring API

    2. Spring 2.0和 2.5的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 新的bean作用域 2.2.2. 更简单的XML配置 2.2.3. 可扩展的XML编写 2.2.4. Annotation(注解)驱动配置 2.2.5. 在classpath中自动搜索组件...

    Spring in Action(第2版)中文版

    16.2协同使用spring和webwork2/struts2 16.3集成spring和tapestry 16.3.1集成spring和tapestry3 16.3.2集成spring和tapestry4 16.4协同使用spring和jsf 16.4.1解析jsf管理的属性 16.4.2解析springbean 16.4.3...

    Spring in Action(第二版 中文高清版).part2

    16.2 协同使用Spring和WebWork 2/Struts 2 16.3 集成Spring和Tapestry 16.3.1 集成Spring和Tapestry 3 16.3.2 集成Spring和Tapestry 4 16.4 协同使用Spring和JSF 16.4.1 解析JSF管理的属性 16.4.2 解析Spring...

    spring 容器.docx

    Spring有两个核心接口:BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口。他们都可代表Spring容器,Spring容器是生成Bean实例的工厂,并且管理容器中的Bean。 Bean是Spring管理的...

    Spring面试题

    2.源代码无关性 Hibernate工作原理及为什么要用? 原理: 1.读取并解析配置文件 2.读取并解析映射信息,创建SessionFactory 3.打开Sesssion 4.创建事务Transation 5.持久化操作 6.提交事务 7.关闭Session 8.关闭...

    第24次课-1 Spring与Hibernate的整合

    Spring配置管理SessionFactory与数据库的连接,在实际的应用中,数据源会采用依赖注入的方式,传递给SessionFactory。 见beans-config_sh.xml 24.3 Spring对Hibernate的简化 24.3.1 概述 Hibernate的持久层访问步骤...

    Spring in Action(第二版 中文高清版).part1

    16.2 协同使用Spring和WebWork 2/Struts 2 16.3 集成Spring和Tapestry 16.3.1 集成Spring和Tapestry 3 16.3.2 集成Spring和Tapestry 4 16.4 协同使用Spring和JSF 16.4.1 解析JSF管理的属性 16.4.2 解析Spring...

    java8源码-Spring5:Spring5新特性

    AOP:面向切面,不修改源代码进行功能增强 Spring特点 方便解耦,简化开发 AOP支持 方便测试 如Junit5 集成其他框架 方便进行事务操作 降低APi开发难度 2.IOC容器 IOC底层原理 XML解析、工厂模式、反射 通过加载配置...

    spring2.5.6源码

    源代码分析,是一件既痛苦又快乐的事情,看别人写的代码是通过的,但当你能够看明白的时候,相信快乐也会随之而来,为了减少痛苦,更快的带来快乐,在这里希望通过这篇文章对觉得困难的朋友有一个帮助。 本文以...

    J2EE应用开发详解

    内容为J2EE应用开发详解中的源代码 第1章 Java Web应用开发简介 1 1.1 Java EE应用概述 1 1.2 Java EE概念 1 1.2.1 Java EE多层模型 1 1.2.2 Java EE体系结构 2 1.3 Java EE的核心API与组件 4 1.4 Web服务器和应用...

Global site tag (gtag.js) - Google Analytics