死磕Spring系列之四 BeanDefinition接口、BeanFactory接口

通过前面的介绍,相信大家对bean的解析,注册的整体流程了解了,知道Spring怎么一步步将xml文档内的配置信息纳入容器中。有几个非常重要的接口,不得不谈。

1.BeanDefinition接口

这个接口,可以理解为xml bean元素的数据载体。通过对比xml bean标签的属性列表和BeanDefinition的属性列表一看便知。

我的理解,是解析XML的过程,就是 xml <bean>元素内容 转换为BeanDefinition对象的过程。而且这个接口,支持层级,对应对象的继承。

有一个类BeanDefinitionHolder,BeanDefinitionHolder,根据名称或者别名持有beanDefinition,它承载了name和BeanDefinition的映射信息。

BeanWarpper:

提供对标准javabean的分析和操作方法:单个或者批量获取和设置属性值,获取属性描述符,查询属性的可读性和可写性等。支持属性的嵌套设置,深度没有限制。

AttributeAccessor:接口定义了最基本的对任意对象的元数据的修改或者获取

BeanMetadataElement:用来传输一个可配置的源对象(源码)

ChildBeanDefinition是一种bean definition,它可以继承它父类的设置,即ChildBeanDefinition对RootBeanDefinition有一定的依赖关系(现在spring源码中已不使用了)。ChildBeanDefinition从父类继承构造参数值,属性值并可以重写父类的方法,同时也可以增加新的属性或者方法。(类同于java类的继承关系)。注意:从spring 2.5 开始,提供了一个更好的注册bean definition类GenericBeanDefinition,它支持动态定义父依赖,方法是 GenericBeanDefinition.setParentName(java.lang.String),GenericBeanDefinition 可以有效的替代ChildBeanDefinition的绝大分部使用场合。我发现在spring3.1.2版本中,该类已经不被使用了。

GenericBeanDefinition是一站式的标准bean definition,除了具有指定类、可选的构造参数值和属性参数这些其它bean definition一样的特性外,它还具有通过parenetName属性来灵活设置parent bean definition。

通常, GenericBeanDefinition用来注册用户可见的bean definition(可见的bean definition意味着可以在该类bean definition上定义post-processor来对bean进行操作,甚至为配置parent name做扩展准备)。RootBeanDefinition / ChildBeanDefinition用来预定义具有parent/child关系的bean definition。

一个RootBeanDefinition定义表明它是一个可合并的bean definition:即在spring beanFactory运行期间,可以返回一个特定的bean。RootBeanDefinition可以作为一个重要的通用的bean definition 视图。

RootBeanDefinition用来在配置阶段进行注册bean definition。然后,从spring 2.5后,编写注册bean definition有了更好的的方法:GenericBeanDefinition。GenericBeanDefinition支持动态定义父类依 赖,而非硬编码作为root bean definition。其中RootBeanDefinition是最常用的实现类,它对应一般性的<bean>元素标签

在 配置文件中可以定义父<bean>和子<bean>,父<bean>用RootBeanDefinition表示, 而子<bean>用ChildBeanDefiniton表示,而没有父<bean>的<bean>就使用 RootBeanDefinition表示。

2.BeanFactory接口

主要是这几个类或接口

ConfigurableBeanFactory:提供配置Factory的各种方法。一般应用用不到,主要为ListableBeanFactory和BeanFactory支持

ListableBeanFactory:根据条件获取bean的配置清单

ConfigurableListableBeanFactory:获取 BeanDefinition 和预先实例化单例 bean 的功能。beanFactory配置清单,指定忽略类型及接口

AutowireCapableBeanFactory:提供自动装配的功能,提供创建,注入,初始化及应用Bean的后处理器

HierarchicalBeanFactory:层级管理

如果,硬性理解这几个类分别有什么含义,有点苦涩。可以逆向思考一下。把这些工厂想象成一个裁缝,会方便理解些。

ConfigurableBeanFactory:你对要求衣服的样式要求

ListableBeanFactory:需求材料清单

AutowireCapableBeanFactory:缝纫机,针线工具

HierarchicalBeanFactory: 套装使用

ConfigurableListableBeanFactory:裁缝的助手

3.ApplicationContext接口

可以说是我们业务系统,主要面对的接口。Spring强大的扩展功能,全在这里实现。通过内部调用BeanFactory初始化,对用户透明。

AbstractRefreshableConfigApplicationContext:指定配置路径

AbstractRefreshableApplicationContext: 支持多次调用refresh.实现了refreshBeanFactory方法,供AbstractApplicationContext调用。

AbstractApplicationContext:模板模式实现初始化过程

  publicvoid refresh() throws BeansException, IllegalStateException {
      synchronized (this.startupShutdownMonitor) {
         // Prepare this context for refreshing.
         prepareRefresh();
 
         // Tell the subclass to refresh the internal bean factory.
         ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 
         // Prepare the bean factory for use in this context.
         prepareBeanFactory(beanFactory);
 
         try {
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);
 
            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);
 
            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);
 
            // Initialize message source for this context.
            initMessageSource();
 
            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();
 
            // Initialize other special beans in specific context subclasses.
            onRefresh();
 
            // Check for listener beans and register them.
            registerListeners();
 
            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);
 
            // Last step: publish corresponding event.
            finishRefresh();
         }
 
         catch (BeansException ex) {
            logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);
 
            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();
 
            // Reset ‘active‘ flag.
            cancelRefresh(ex);
 
            // Propagate exception to caller.
            throw ex;
         }
      }
   }

下面是针对该过程的各步骤分析(来自Spring 深度源代码分析)

时间: 12-24

死磕Spring系列之四 BeanDefinition接口、BeanFactory接口的相关文章

死磕Spring系列之一:准备阅读Spring源码环境

死磕Spring系列前言 死磕spring系列博客,是对Spring进行源码级阅读.工作以来,一直接触spring框架,可以说对spring框架的配置使用已经非常熟练了.个人感觉:Spring技术非常强大,简单的xml标签配置,就可以开启非常强大的支持功能,囊括J2EE企业应用的方方面面.使用归使用,但是却对spring底层设计和实现,一知半解."到底是什么优秀的设计,能让Spring无所不能,无所不包".最后,就有了我想研读Spring 源码的动力. 阅读任何任何一门框架源码,其实和

死磕Spring系列之三,XML解析相关

通过第2章的介绍,应该知道Spring如何从XML一步步解析成BD对象并注册到容器中,这一过程有个概要认识了. 接下来开始详细分析与XML相关的那些事. 一.首先看一下使用的XML文档. <?xmlversion="1.0"encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http

死磕Spring AOP系列4:剖析AOP schema方式原理

这个是<死磕Spring AOP系列>第4个.已经讲过的内容 死磕Spring AOP系列3:剖析Bean处理器之DefaultAdvisorAutoProxyCreator 死磕Spring AOP系列2:剖析Bean处理器之BeanNameAutoProxyCreator 死磕Spring AOP系列1:编程式实现AOP 通过前3篇,大家应该可以清楚的知道:AOP代理原理有3元素 BeanPostProcessor,作为代理对象初始入口 Advisor&Pointcut&M

死磕Spring AOP系列2:剖析Bean处理器之BeanNameAutoProxyCreator

通过前一篇<死磕Spring AOP系列1:编程式实现AOP>,学习了Spring对代理的底层支持,认识了ProxyFactory对象,及从类设计层面认识了PointCut&Advisor&Advice&Interceptor,还认识了AdvisorChainFactory对象,知道了底层Advisor的底层链式结构.但是,上篇我们仅仅是通过Spring编程式实现的"AOP"效果,这种方式,实际开发时,如果这样用就太LOW了.今天,主要认识一个生成代

死磕Spring AOP系列3:剖析Bean处理器之DefaultAdvisorAutoProxyCreator

导航 死磕Spring AOP系列1:编程式实现AOP 死磕Spring AOP系列2:剖析Bean处理器之BeanNameAutoProxyCreator 这是<死磕Spring AOP系列>的第三篇.经过前面的讲解,已经掌握了以下知识点 Spring AOP的底层支持,是基于ProxyFactory+ProxyConfig+Advisor生成的 Spring容器的代理对象生成:在Bean生命周期过长中调用BeanPostProcessor,将对象进行包装,生成代理对象. Advisor的指

死磕Spring AOP系列1:编程式实现AOP

作为[死磕Spring AOP]系列的第一篇, 这个系列是AOP源码分析级别的文章.由于现在AOP已经不是什么高深的技术,网上的例子也比比皆是,不论是xml schema,还是annotation声明式.相信用过Spring的朋友,都可以信手拈来. 本系列文章的原则 如何配置AOP不是重点 AOP相关概念讲解不是重点 AOP 底层代码设计才是重点 本篇的主要内容 认识ProxyFactory,并通过该工厂类,将"日志"和"安全校验"代码切入到业务逻辑中 分析代理对象

死磕Spring AOP系列5:设计模式在AOP中的使用

死磕Spring AOP系列3:剖析Bean处理器之DefaultAdvisorAutoProxyCreator 死磕Spring AOP系列2:剖析Bean处理器之BeanNameAutoProxyCreator 死磕Spring AOP系列1:编程式实现AOP 死磕Spring AOP系列4:剖析AOP schema方式原理 通过前面的死磕,应该对AOP的原理都掌握了.annotation配置AOP,再没有讲的必要了.annotation和xml schema两种方式,仅仅是声明方式不同而已

【死磕 Spring】----- IOC 之 加载 Bean

先看一段熟悉的代码: ClassPathResourceresource new ClassPathResource("bean.xml");DefaultListableBeanFactoryfactory new DefaultListableBeanFactory();XmlBeanDefinitionReaderreader new XmlBeanDefinitionReader(factory);reader.loadBeanDefinitions(resource);这段代

【死磕 Spring】----- IOC 之 获取验证模型

原文出自:http://cmsblogs.com 在上篇博客[死磕Spring]----- IOC 之 加载 Bean 中提到,在核心逻辑方法 doLoadBeanDefinitions()中主要是做三件事情. 调用 getValidationModeForResource() 获取 xml 文件的验证模式 调用 loadDocument() 根据 xml 文件获取相应的 Document 实例. 调用 registerBeanDefinitions() 注册 Bean 实例. 这篇博客主要分析