Spring框架之beans源码彻底解析

导读:Spring能够说是Java企业开发里最重要的技术。而Spring两大核心IOC(Inversion of Control控制反转)和AOP(Aspect Oriented Programming面向切面编程)其中又以IOC最为核心。IOC容器是Spring的核心模块,Spring提供了两种类型的容器,一个是BeanFactory,一个是ApplicationContext,而ApplicationContext是BeanFactory扩展来的。java

本文就Spring框架的beans源码进行解析,主要从如下几个方面进行:一是Spring框架介绍,对Spring总体架构有个直观的了解;二是对beans源码文件清单进行梳理,共12大类,257个java文件,对DefaultListableBeanFactory等一些核心类进行了重点分析;三是对BeanDefinition进行解析,BeanDefinition 在 spring 中贯穿始终,是spring 一块基石;四是对Bean默认标签解析全过程进行了分析;五是以doGetBean函数为核心,分析Bean的加载过程;六是介绍ApplicationContext和BeanFactory两种容器的Bean的生命周期。node


文章目录
web

1、Spring框架简介算法

2、Beans源码文件清单spring

  一、  org.springframework.beans包含的类和接口数据库

  二、  org.springframework.beans.annotation包含的类和接口express

  三、  org.springframework.beans.propertyeditors包含的类和接口编程

  四、  org.springframework.beans.support包含的类和接口设计模式

  五、  org.springframework.beans.factory包含的类和接口数组

  六、  org.springframework.beans.factory.annotation包含的类和接口

  七、  org.springframework.beans.factory.config包含的类和接口

  八、  org.springframework.beans.factory.parsing包含的类和接口

  九、  org.springframework.beans.factory.serviceloader包含的类和接口

  十、org.springframework.beans.factory.support包含的类和接口

  十一、org.springframework.beans.factory.wiring包含的类和接口

  十二、org.springframework.beans.factory.xml包含的类和接口

3、BeanDefinition解析

  (一)BeanDefinition是什么

  (二)BeanDefinition属性

  (三)BeanDefinition实现类

  (四)BeanDefinition的载入和解析

4、Bean默认标签解析

  (一)默认标签

  (二)bean标签的解析及注册

  (三)解析BeanDefinition

  (四)建立用于承载属性的GenericBeanDefinition

  (五)解析各类属性

5、Bean的加载

  (1)转换对应的beanName

  (2)尝试从缓存中加载单例

  (3)bean的实例化

  (4)原型模式(prototype)的依赖检查

  (5)检测parentBeanFactory

  (6)GenericBeanDefinition转为RootBeanDefinition

  (7)寻找依赖

  (8)依据scope建立bean

  (9)类型转换

6、Bean的生命周期

  (1)ApplicationContext Bean生命周期

  (2)BeanFactory Bean生命周期

 

1、Spring框架简介

  Spring框架是一个Java平台,用来提供全面的基础设施支持开发Java应用程序, Spring负责处理基础设施部分,这样你就能够专一于应用程序部分。Spring框架内,把一级对象经过设计模式封装起来,这样你就能够集成到本身的应用程序中而不用关注他们是如何在后台工做的。

  目前,Spring框架按照功能组织成大约20个模块。这些模块分为核心容器、数据访问/集成、Web、AOP(面向切面的编程)、instrument(支持和类加载器的实现来在特定的应用服务器上使用)、消息和测试,以下图所示。

从上面能够看出Spring主要分红六个模块:

  1.Spring核心容器:核心容器是Spring框架的重要组成部分,也能够说是Spring框架的基础。他在整个框架中的做用是负责管理对象的建立,管理,配置等操做。其主要包含spring-core、spring-beans、spring-context、spring-expression组件。

  2.面向切面编程:Spring框架还提供了面向切面编程的能力,利用面向切面编程,能够实现一些面向对象编程没法很好实现的操做。例如,将日志,事务与具体的业务逻辑解耦。其主要包含spring-aop、spring-aspects组件。

  3.Instrumentation:该模块提供了为JVM添加代理的功能,该模块包含spring-instrument、spring-instrument-tomcat组件,使用较少,没必要过度关注。

  4.数据访问与集成:Spring框架为了简化数据访问的操做,包装了不少关于数据访问的操做,提供了相应的模板。同时还提供了使用ORM框架的能力,能够与不少流行的ORM框架进行整合,如hibernate,mybatis等等的著名框架。还实现了数据事务的能力,可以支持事务。包含spring-jdbc、spring-tx、spring-orm、spring-oxm、spring-jms、spring-messaging组件。

  5.Web和远程调用:Spring框架支持Web开发,以及与其余应用远程交互调用的方案。包含spring-web、spring-webmvc、spring-websocket、spring-webmvc-portlet组件。

  6.Spring测试:Spring框架提供了测试的模块,能够实现单元测试,集成测试等等的测试流程,整合了JUnit或者TestNG测试框架。包含spring-test组件。

 

咱们为何要使用Spring框架?简单来讲,使用Spring框架能够带来如下好处:

  一、轻量:非入侵性的、所依赖的东西少、资源占用少、部署简单,不一样功能选择不一样的 jar 组合。

  二、容器:工厂模式实现对 JavaBean 进行管理,经过控制反转(IOC)将应用程序的配置和依赖性与应用代码分开。

  三、松耦合:经过 xml 配置或注解便可完成 bean 的依赖注入。

  四、AOP:经过 xml 配置 或注解便可加入面向切面编程的能力,完成切面功能,如日志,事务等的统一处理。

  五、方便集成:经过配置和简单的对象注入便可集成其余框架,如 Mybatis、Hibernate。

  六、丰富的功能:JDBC层抽象、事务管理、MVC、Java Mail、任务调度、JMX、JMS、JNDI、EJB、动态语言、远程访问、Web Service等。

 

其中,最核心的就是上述的2和4:IOC(控制反转)和AOP(面向切面编程)。

  IOC:在平时的java应用开发中,咱们要实现某一个功能或者说是完成某个业务逻辑时至少须要两个或以上的对象来协做完成。在没有使用Spring的时候,每一个对象在须要使用他的合做对象时,本身均要使用像new object() 这样的语法来将合做对象建立出来,这个合做对象是由本身主动建立出来的,建立合做对象的主动权在本身手上,本身须要哪一个合做对象,就主动去建立,建立合做对象的主动权和建立时机是由本身把控的,而这样就会使得对象间的耦合度高了。好比A对象须要使用合做对象B来共同完成一件事,A要使用B,那么A就对B产生了依赖,也就是A和B之间存在一种耦合关系,而且是紧密耦合在一块儿。而使用了Spring以后就不同了,建立合做对象B的工做是由Spring来作的,Spring建立好B对象,而后存储到一个容器里面,当A对象须要使用B对象时,Spring就从存放对象的那个容器里面取出那个B对象,而后交给A对象使用,至于Spring是如何建立那个对象,以及何时建立好,A对象不须要关心这些细节问题,A获得Spring给以后,两个对象一块儿协做完成要完成的工做便可。

  因此控制反转是将建立对象的控制权进行转移,之前建立对象的主动权和建立时机是由本身把控的,而如今这种权力转移到第三方,好比转移交给了IOC容器,它就是一个专门用来建立对象的工厂,你要什么对象,它就给你什么对象,有了 IOC容器,依赖关系就变了,原先的依赖关系就没了,它们都依赖IOC容器了,经过IOC容器来创建它们之间的关系。

  AOP能够说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来创建一种对象层次结构,用于模拟公共行为的一个集合。不过OOP容许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码每每横向地散布在全部对象层次中,而与它对应的对象的核心功能毫无关系对于其余类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为横切,在OOP设计中,它致使了大量代码的重复,而不利于各个模块的重用。

  同OOP技术偏偏相反,AOP利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减小系统的重复代码,下降模块之间的耦合度,并有利于将来的可操做性和可维护性。

 

2、Beans源码文件清单

  spring项目源码由多个子项目组成,如spring-beans,spring-context,spring-core,spring-aop,spring-web,spring-webmvc等,整个项目结构以下图:

其中spring beans有以下的源文件包:

  一、org.springframework.beans:包含了操做java bean的接口和类。

  二、org.springframework.beans.annotation:支持包,提供对java 5注解处理bean样式的支持。

  三、org.springframework.beans.propertyeditors:属性编辑器,用来将string类型的值转换为object类型。

  四、org.springframework.beans.support:org.springframework.beans的支持包,好比一组bean的排序和保持工具类等。

  五、org.springframework.beans.factory:实现spring轻量级IOC容器的核心包。

  六、org.springframework.beans.factory.annotation:配置基于注解驱动的bean的支持包。

  七、org.springframework.beans.factory.config:bean工厂的SPI接口和配置相关的处理类。

  八、org.springframework.beans.factory.parsing:bean definition解析的支持基础类。

  九、org.springframework.beans.factory.serviceloader:jdk1.6 ServiceLoader基础类的支持包。

  十、org.springframework.beans.factory.support:org.springframework.beans.factory 包的支持类。

  十一、org.springframework.beans.factory.wiring:一种决定一个bean实例的元数据的机制。

  十二、org.springframework.beans.factory.xml:包含了一个基于xml的beanFactory实现,也包含一个标准的spring-beans的dtd。

 

  在介绍beans的类和接口以前,先理清下bean的概念,在 Spring 中,构成应用程序主干并由Spring IOC容器管理的对象称为bean。bean是一个由Spring IOC容器实例化、组装和管理的对象。简而言之,bean是对象,并且由Spring中IOC容器进行管理,咱们的应用程序由一个个bean构成。

一、org.springframework.beans包含的类和接口

1.1  BeanInfoFactory:建立java.beans.BeanInfo实例的策略,定义了方法BeanInfo getBeanInfo()。

1.2 ExtendedBeanInfo:BeanInfo接口的实现类,BeanInfo接口是在java.beans包中的。

1.3 ExtendedBeanInfoFactory:BeanInfoFactory接口的实现,用来评估bean的class是否有不知足JavaBean规范的set方法,于是是否知足Spring ExtendedBeanInfo做为内省的候选。

 

1.4 BeanWrapper:Spring底层JavaBean公共基础的核心接口。一般不直接使用,而是经过BeanFactory间接使用。做用:提供对标准javabean的分析和操做方法:单个或者批量获取和设置属性值,获取属性描述符,查询属性的可读性和可写性等。支持属性的嵌套设置,深度没有限制。

1.5 CachedIntrospectionResults:内部类。在BeanWrapperImpl类中会用到,为这个类的javabean缓存属性描述信息,以提升效率,减少开销。

1.6 BeanWrapperImpl:BeanWrapper的默认实现。能够根据需求,将集合与数组的值转换到对应目标对象的集合和数组。自定义的属性编辑器经过属性编辑器的setValue,setAsText方法实现上述的转换功能。

 

1.7 Mergeable:表明一个对象的值能够和父对象的值进行合并的接口。其主要的子类有:ManagedList、ManagedArray、ManagedMap、ManagedProperties、ManagedSet。这几个类在org.springframework.beans.factory 包中。

1.8 BeanMetadataElement:传送配置源对象的超级接口。定义了惟一的方法:Object getSource(),其子类和子接口以下图:

 

1.9 BeanMetadataAttribute:bean definition定义中的属性-键值对(key-value)容器。

1.10 BeanMetadataAttributeAccessor:AttributeAccessorSupport的拓展,为了追踪对象定义源。

 

1.11 GenericTypeAwarePropertyDescriptor:JavaBeans的PropertyDescriptor类的拓展,重载了getPropertyType函数。

1.12 PropertyDescriptorUtils:抽象类,PropertyDescriptor内部使用。PropertyDescriptor(属性描述器)在软件包 java.beans中,用来表示JavaBean 经过存储器方法导出的一个属性。

1.13 PropertyMatches:根据一个可配置的距离计算一个属性的匹配度。可同时用于java bean的成员变量(fields)与属性(properties)。其核心函数calculateStringDistance,利用Levenshtein算法计算两个字符串的类似度。另解析下Java中成员变量(Fields)和属性(Properties)的区别: 成员变量Fields就是定义的字段。根据SUN官方定义,属性是指get或者set方法名去掉get或者set后,把剩余的部分首字母改成小写后,即为这个类的属性。

1.14 PropertyAccessor:获取和设置属性(例如对象bean的属性,对象的Field)的通用接口,它用来做为BeanWrapper的基础接口。其继承关系以下图:

1.15  AbstractPropertyAccessor:PropertyAccessor接口的抽象实现。

1.16  AbstractNestablePropertyAccessor:继承自AbstractPropertyAccessor,也是ConfigurablePropertyAccessor的一种,能够为典型的一些应用场景提供支持。

1.17 ConfigurablePropertyAccessor:PropertyAccessor配置方法的封装接口。是BeanWrapper的父接口。

1.18 DirectFieldAccessor:ConfigurablePropertyAccessor接口的实现类,用来直接获取实例的字段(f ield)。

1.19 PropertyAccessorFactory:获取PropertyAccessor实例简单工厂,特别是BeanWrapper实例(BeanWrapper继承自PropertyAccessor)。

1.20 PropertyAccessorUtils:PropertyAccessor类获取和设置属性的一些工具方法。

 

1.21 PropertyEditorRegistrar:用一个属性编辑器注册器(PropertyEditorRegistry)注册一个自定义的属性编辑器(PropertyEditor)的策略接口。

1.22 PropertyEditorRegistry:属性编辑器注册器。封装了JavaBean属性编辑器的注册方法。主要函数为void registerCustomEditor()。

1.23 PropertyEditorRegistrySupport:PropertyEditorRegistry接口的基本实现类。主要做为BeanWrapperImpl父类使用。

 

1.24 PropertyValue:一个对象,用来保存一个bean单独属性值信息。用对象来保存PropertyValue(name, value)信息,相对于map保存能够提供更大的灵活性。

1.25 PropertyValues:包含了一个或者多个PropertyValue对象,一般用做特定的一个目的bean的属性更新。

1.26 MutablePropertyValues:PropertyValues接口的默认实现,提供了对属性的一些简单操做,好比get、add、set、merge、remove方法等。

1.27 PropertyValuesEditor:PropertyValues 对象的编辑器。

 

1.28 TypeConverter:定义了类型转换方法的接口。将值转换成指定的类型。

1.29 TypeConverterDelegate:内部用的类,用来将属性值转换为目标类型的值。

1.30 SimpleTypeConverter:TypeConverter接口的简单实现,它不会针对一个特定的目标进行操做。

1.31 TypeConverterSupport:TypeConverter接口的基本实现类,使用了代理typeConverterDelegate。这个类主要用做BeanWrapperImpl的基类使用。

 

1.32 BeanUtils:JavaBeans的静态工具方法,用来初始化bean,检查bean属性类型,复制bean属性等。

 

1.33 BeansException:在beans包和子包中所抛出的全部异常的抽象超类。

1.34 BeanInstantiationException:bean初始化失败时抛出的异常。

1.35 FatalBeanException:在bean包和子包中遇到的不可恢复问题抛出的异常,例如:当引用一个无效的bean属性时抛出的InvalidPropertyException异常。

1.36 ConversionNotSupportedException:当一个bean的属性没有适合的编辑器或者转换器时所抛出的异常。

1.37 MethodInvocationException:当一个bean属性的get和set方法抛出异常时抛出该异常,相似于InvocationTargetException。

1.38 NullValueInNestedPathException:当获取一个内嵌属性路径的属性时遇到空指针异常时抛出的异常。

1.39 TypeMismatchException:当试图设置bean属性时抛出的类型不匹配异常。

1.40 InvalidPropertyException:遇到非法的bean property时异常类。

1.41 NotReadablePropertyException:当试图获取一个不可读属性的属性值时抛出的异常,典型场景bean属性没有get方法。

1.42 NotWritablePropertyException:当试图向一个不可写属性写入属性值时抛出的异常,典型场景bean属性没有set方法。.

1.43 PropertyAccessException:获取属性相关的异常超类,例如类型不匹配或者目标调用异常。

1.44 PropertyBatchUpdateException组合异常,由多个的单个PropertyAccessException实例组成。

 

二、org.springframework.beans.annotation包含的接口和类

2.1 AnnotationBeanUtils:JavaBean类型注解的通用工具方法。定义了一个静态方法:public static void copyPropertiesToBean(),将指定Annotation的属性复制到目标bean中。若是属性在excludeProperties中定义了,那么就不会被复制。

 

三、org.springframework.beans.propertyeditors包含的接口和类

  属性编辑器,用来将string类型的值转换成object类型的。他们都继承自PropertyEditorSupport,这个类能够用于自定义的类型转换,继承后重写了public void setAsText(),public String getAsText() 两个方法。注意PropertyEditor和PropertyEditorSupport都是java本身定义的,不是Spring的。包含的类有:

3.1  ByteArrayPropertyEditor

3.2  CharacterEditor

3.3  CharArrayPropertyEditor

3.4  CharArrayPropertyEditor

3.5  ClassArrayEditor

3.6  ClassEditor

3.7  CurrencyEditor

3.8  CustomBooleanEditor

3.9  CustomCollectionEditor

3.10  CustomDateEditor

3.11  CustomMapEditor

3.12  CustomNumberEditor

3.13  FileEditor

3.14  InputSourceEditor

3.15  InputStreamEditor

3.16  LocaleEditor

3.17  PathEditor

3.18  PatternEditor

3.19  PropertiesEditor

3.20  ReaderEditor

3.21  ResourceBundleEditor

3.22  StringArrayPropertyEditor

3.23 StringTrimmerEditor

3.24  StringTrimmerEditor

3.25  URIEditor

3.25  URLEditor

3.27  UUIDEditor

3.28  ZoneIdEditor

 

四、org.springframework.beans.support包含的接口和类

4.1  ArgumentConvertingMethodInvoker:MethodInvoker的子类,经过TypeConverter将真实目标方法的指定参数进行转换。

4.2  MutableSortDefinition:SortDefinition接口的可变实现。支持在对同一个属性值进行设置的时候能够利用升序排列的值进行切换。

4.3  PagedListHolder:PagedListHolder是一个简单的状态保持,它处理一组对象,将它们分页。分页的起始页从0开始。主要用在web网站的用户界面上。

4.4  PropertyComparator:对两个bean进行比较,经过BeanWrapper来比较指定bean的属性。

4.5  ResourceEditorRegistrar:继承了PropertyEditorRegistrar,使用资源编辑器来填充指定的PropertyEditorRegistry。

4.6  SortDefinition:根据一个指定的属性对一组bean实例进行排序的定义类。isAscending为True时进行升序排列,为False进行降序排列。

 

五、org.springframework.beans.factory包含的接口和类

5.1  Aware:它是一个标签,内部没有任何属性或者方法。它是一个超级接口,实现它的子接口的bean标志着在spring容器中能够被特定框架的对象通知到,经过回调方式的方法来完成这种通知。继承关系以下图:

5.2  BeanClassLoaderAware:容许一个获取它的classLoader(即当前bean factory加载bean类使用的class loader)的回调类,实现了void setBeanClassLoader(ClassLoader classLoader)。

5.3  BeanFactoryAware:实现此接口的bean能够获取到它们本身的Beanfactory。好比,bean能够经过factory寻找一些具备协做关系的beans。

5.4  BeanNameAware:实现此接口的bean能够在一个bean factory中获取到它们的bean名称。可是须要注意的是,并不推荐一个经过一个bean name去定位bean,在外部配置中,这种对应关系并不严格对应。

5.5  NamedBean:对应BeanNameAware接口,返回bean的名称。函数String getBeanName()。

 

5.6  BeanFactory:获取spring bean容器的根接口。其主要函数有getBean()、getBeanProvider()、containsBean()、isSingleton()、isPrototype()、isTypeMatch()、getType()、getAliases()。其继承关系以下图:

5.7  BeanFactoryUtils:beanFactory上的操做方法工具类,特别是在ListableBeanFactory接口上。包括返回bean的个数,bean的名字,bean实例等,考虑到了一些具备嵌套关系的hierarchy factory,而若是这些方法在ListableBeanFactory中不须要考虑这些。

5.8  HierarchicalBeanFactory:子接口,实现此接口的bean factory具备层次结构便可以获取父BeanFactory。方法 getParentBeanFactory()获取父BeanFactory;方法containsLocalBean()判断本地bean factory是否含有指定名字的bean,不考虑在父BeanFactory中的状况。

5.9  ListableBeanFactory:beanFactory接口的实现,实现此接口的beanFactory能遍历他们内部的全部bean实例,而不用根据客户请求经过名字一个一个的去搜索bean。提供的函数以下:

  containsBeanDefinition();判断factory是否包含指定命名的bean definition;

  getBeanDefinitionCount();返回在factory中定义的bean的个数;

  getBeanDefinitionNames();返回该factory中定义的全部bean的名字;

  getBeanNamesForType();返回指定类型的bean的名字;

  getBeansOfType();返回指定类型的bean实例;

  getBeanNamesForAnnotation(); 返回被指定的标签标注的全部bean的名字;

  getBeansWithAnnotation();返回被指定标签标注的全部bean实例。

 

5.10  FactoryBean:实现了此接口的bean不能看作一个一般意义上的bean,一个FactoryBean虽然以bean的形式来定义,但它暴露的对象(getObject())一般是它建立的对象,而不是做为一个bean实例暴露本身。

5.11  SmartFactoryBean:FactoryBean接口的扩展实现。实现该接口能够代表每次是否返回的都是独立的实例,由于用isSingleton()函数判断为假,代表非单例模式,但这并不足以代表返回的都是独立的实例。

 

5.12  ObjectFactory:一个对象工厂,当触发时会返回全部对象的实例(能够是共享的或者独立的)。

5.13  ObjectProvider:继承自ObjectFactory,ObjectFactory的一个变种,专门用来为注入点服务。

5.14  InjectionPoint:注入点的简单描述,指向一个方法或者构造函数的参数或者成员变量(field)。

5.15  InitializingBean:实现此接口的bean在BeanFactory设置为它们的属性时只须要执行一次,例如:初始化定制或者仅仅检查必须存在的属性是否已经设置完成等等。

5.16  SmartInitializingSingleton:回调接口,当一个bean工厂建立时,单例singleton实例化阶段结束时被触发。一些单例模式的bean能够实现此接口,在单例实例作完一些规律性、常作的初始化能够用来作一些初始化工做。以免突发的Early initialization产生的负面效果。好比ListableBeanFactory中的getBeansOfType函数调用。注:对于单件的初始化有(Lazy Initialization)和(Early initialization)两种方法。

5.17  BeanCreationException:beanfactory在试图经过bean definition建立一个bean时遇到错误而抛出的异常。

5.18  BeanCreationNotAllowedException:若当前不容许建立一个bean时(例如在beanFactory关闭过程当中)而试图去获取bean的请求时抛出的异常。

5.19  BeanCurrentlyInCreationException:一个bean的引用当前正在建立过程当中抛出的异常。

5.20  BeanDefinitionStoreException:beanFactory遇到一个无效的bean definition抛出的异常 。

5.21  BeanExpressionException:获取一个表达式的值失败时抛出的异常。

5.22  BeanInitializationException:bean初始化异常时抛出。

5.23  BeanIsAbstractException:当试图获取一个定义为abstract的bean definition时抛出的异常。

5.24  BeanIsNotAFactoryException:当一个bean不是工厂,但用户试图经过给定bean名称访问工厂。

5.25  BeanNotOfRequiredTypeException:当一个bean的类型和指望类型不匹配时抛出的异常。

5.26  CannotLoadBeanClassException:BeanFactory不能加载指定bean的class类时抛出的异常。

5.27  FactoryBeanNotInitializedException:工厂bean没有初始化异常。

5.28  NoSuchBeanDefinitionException:没有该bean definition异常。

5.29 NoUniqueBeanDefinitionException:返回多个bean definition异常。

5.30  UnsatisfiedDependencyException:当有依赖检查时,在bean factory定义中,bean的依赖或者属性没有指定时抛出的异常。

 

六、org.springframework.beans.factory.annotation包含的接口和类

6.1  AnnotatedBeanDefinition:BeanDefinition接口的扩展,BeanDefinition在org.springframework. beans.factory.config包中。

  它暴露了它的bean 类的AnnotationMetadata,不须要加载类。提供了一个getMetadata()方法来获取该bean definition的注解元数据, ClassMetadata定义了一个特定类的抽象元数据,不须要加载此类便可访问,主要方法有:

  1)String getClassName()返回该类的名称。

  2)boolean isInterface()返回该类是不是接口。

  3)boolean isAbstract()返回该类是否为抽象类。

  4)boolean isConcrete()返回该类是否为具体类。

  5)boolean isFinal()返回该类是否为final类。

  6)boolean hasSuperClass()返回该类是否有父类。

  7)String getSuperClassName()返回父类的名称,没有的话返回null。

  8)String[] getInterfaceNames()返回继承的接口数组,若是没有,返回空。

  9)String[] getMemberClassNames()返回引用的类的名称。

6.2  AnnotatedGenericBeanDefinition:继承自GernericBeanDefinition和AnnotatedBeanDefinition,经过暴露AnnotatedBeanDefinition接口来增长对注解元数据的支持。GernericBeanDefinition在org.springframework.beans.factory.support包中,是一站式的标准bean Definition。

 

Spring自带依赖注入注解:

  1 @Required:依赖检查;

  2 @Autowired:按类型自动装配,用于替代基于XML配置的自动装配。基于@Autowired的自动装配,默认是根据类型注入,能够用于构造器、字段、方法注入

  3 @Value:注入int、float、String等基本数据类型,只能标注在成员变量、setter方法上。

  4 @Qualifier:限定描述符,用于细粒度选择候选者。@Qualifier限定描述符除了能根据名字进行注入,但能进行更细粒度的控制如何选择候选者。@Qualifier(value = "限定标识符")

 

6.3  Required:public @interface Required 依赖检查。

6.4  Autowired:public @interface Autowired:能够对成员变量、方法和构造函数进行标注,来完成自动装配的工做。

6.5  Value:public @interface Value:用于注入SpEL表达式,能够放置在字段方法或参数上。

6.6  Qualifier:@Qualifier(value = "限定标识符") 。对应于基于XML配置中的标签,@Qualifier限定描述符除了能根据名字进行注入,但能进行更细粒度的控制如何选择候选者@Qualifier(value = "限定标识符") 。

6.7  Configurable:@Configurable 注解中的autowire属性就可让Spring来自动装配。

 

6.8  RequiredAnnotationBeanPostProcessor(@required注解实现类):实现了BeanPostProcessor,对配置了Required注解的javaBean属性进行强制检查。

6.9  AutowiredAnnotationBeanPostProcessor (Autowired注解实现类):实现了BeanPostProcessor接口,它自动绑定注解的field,setter方法和任意配置方法。AutowiredAnnotationBeanPostProcessor 间接继承了BeanPostProcessor,它自动绑定注解的field,setter方法和任意的配置方法。当检测到5个java注解时这些成员被注入其中。spring默认的注解为@Autowired和@Value。另外:也支持JSR-330的@inject注解,做为@Autowired的替代方案。

6.10  AnnotationBeanWiringInfoResolver(@configurable注解实现):继承自BeanWiringInfoResolver,使用configurable的注解来查找哪些类须要自动绑定。设置 @Configurable 注解中的autowire属性就可让Spring来自动装配:@Configurable(autowire= Autowire.BY_TYPE) 或者 @Configurable(autowire=Autowire.BY_NAME,这样就能够按类型或者按名字自动装配了。

6.11  QualifierAnnotationAutowireCandidateResolver(@qualifier的注解实现类):间接实现了AutowireCandidateResolver,对要自动绑定的field或者参数和bean definition根据@qualifier注解进行匹配。同时也支持经过@value注解来绑定表达式的值。AutowireCandidateResolver是一个策略接口,由它来决定特定的bean definition对特定的依赖是否能够做为一个自动绑定的候选项。

6.12  InitDestroyAnnotationBeanPostProcessor(初始化和销毁方法的注解实现类):间接继承了BeanPostProcessor,实现了经过注解来初始化init和销毁destroy方法。是spring的InitializingBean和DisposableBean回调接口的注解实现。

 

6.13  BeanFactoryAnnotationUtils:关联注解的bean的查询的工具方法,例如spring的@Qualifier注解。

6.14  CustomAutowireConfigurer:继承了BeanFactoryPostProcessor,它使自定义的自动绑定qualifier类型的注册更便利。.

6.15  InjectionMetadata:管理注入元数据的内部类。

6.16  Lookup:@Lookup的注解,这是一个做用在方法上的注解,被其标注的方法会被重写,而后根据其返回值的类型,容器调用BeanFactory的getBean()方法来返回一个bean。

好比:若是有一个类C,须要用到类B,若是使用@Autowired注解注入B,那么B每次调用都是同一个对象,即便B不是单例的,如今我但愿每次调用B都是不同的,那么实现方案有2个:方案A : 每次从容器中获取B;方案B: 使用@lookup注解。

6.17  ParameterResolutionDelegate:代理类,用来解析外部构造函数或方法上的自动装配的参数。

6.18 Autowire:决定自动绑定状态的枚举,即一个bean的依赖是否由spring容器使用setter方式自动注入。这个是spring DI的核心概念。

 

七、org.springframework.beans.factory.config包含的接口和类

FactoryBean和BeanFactory区别:

  FactoryBean:Spring 中有两种类型的Bean,一种是普通Bean,另外一种是工厂Bean 即 FactoryBean。FactoryBean跟普通Bean不一样,其返回的对象不是指定类的一个实例,而是该FactoryBean的getObject方法所返回的对象。建立出来的对象是否属于单例由isSingleton中的返回决定。Spring自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂Bean的细节,给上层应用带来了便利。FactoryBean 一般是用来建立比较复杂的bean,通常的bean 直接用xml配置便可,但若是一个bean的建立过程当中涉及到不少其余的bean 和复杂的逻辑,用xml配置比较困难,这时能够考虑用FactoryBean。

  BeanFactory:以Factory结尾,表示它是一个工厂类(接口), 是负责生产和管理bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及创建这些对象间的依赖。BeanFactory只是个接口,并非IOC容器的具体实现,可是Spring容器给出了不少种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等。

 

7.1  AbstractFactoryBean:实现了FactoryBean的简单模板超类,它根据singleton标志来决定是建立一个单例仍是一个prototype对象。

7.2  ListFactoryBean:共享一组(list)实例的简单工厂bean。

7.3  MapFactoryBean:共享一组(map)实例的简单工厂bean。

7.4  SetFactoryBean:共享set实例的简单工厂bean。

7.5  MethodInvokingFactoryBean:一个有返回值的工厂bean,它返回触发一个静态或者实例的方法的结果。

7.6  MethodInvokingBean:一个简单的method invoker bean,和MethodInvokingFactoryBean不一样,它并不返回触发一个方法的结果,而是仅仅返回触发一个目标方法。

7.7  FieldRetrievingFactoryBean:检索静态或者非静态Field的值的工厂bean。

7.8  PropertyPathFactoryBean:经过给定目标对象计算属性路径的工厂bean。

7.9  ObjectFactoryCreatingFactoryBean:一个有返回值的工厂bean,它返回ObjectFactory。

7.10  ProviderCreatingFactoryBean:返回一个JSR-330 Provider的工厂bean,JSR-330 Provider反过来从beanFactory返回一个bean资源。JSR-330 是 Java 的依赖注入标准。

7.11  ServiceLocatorFactoryBean:继承自FactoryBean,在beanFactory中建立一个动态代理,来代理一个具备一个或者多个服务或者类型的接口。

7.12  PropertiesFactoryBean:它支持从classpath位置的文件中读取属性实例的工厂bean。

7.13  YamlMapFactoryBean:为读取YAML源文件的Map的工厂,保持YAML声明的值类型和结构的原样。

7.14  YamlProcessor:YAML 是专门用来写配置文件的语言,很是简洁和强大,远比 JSON 格式方便。它实质上是一种通用的数据串行化格式。该类做为YAML factories基类。

7.15  YamlPropertiesFactoryBean:从YAML源文件中读取属性的工厂,用来暴露字符串属性值扁平型组织结构。

 

7.16  AutowireCapableBeanFactory:beanFactory的扩展接口,实现了自动绑定功能。这个接口的两个主要方法是:autowire:使用给定的自动绑定策略,来给一个类的新实例进行初始化。autowireBeanProperties使用名称或者类型来自动绑定给定bean实例的属性。

7.17  ConfigurableBeanFactory:将会被大部分beanFactory实现的配置接口。为对bean factory进行配置提供一些功能服务,包括BeanFactory接口中的一些函数。这个接口并不用于普通的应用代码,而是用于同BeanFactory或 ListableBeanFactory一块儿出现使用。

7.18  ConfigurableListableBeanFactory:将会被大部分ListablebeanFactory实现的配置接口。除了ConfigurableBeanFactory,该接口也提供分析和修改bean definitions的功能函数,也能预实例化单例对象。

       

7.19  BeanDefinition:一个bean实例的描述,它含有属性值、构造参数值。它的实现子类还提供更多的信息。bean的定义BeanDefinition,包装BeanWrapper是java bean的基础。能够这么说,是spring的基石,再怎么强调它的重要性都不为过。

  BeanDefinition 做用:一个BeanDefinition描述了一个bean的实例,包括属性值,构造方法参数值和继承自它的类的更多信息。BeanDefinition仅仅是一个最简单的接口,主要功能是容许BeanFactoryPostProcessor,例如PropertyPlaceHolderConfigure(PropertyPlaceholderConfigurer是BeanFactoryPostProcessor的一个重要实现)可以检索并修改属性值和别的bean的元数据。

  BeanDefinition的继承关系:(1)父接口:AttributeAccessor、BeanMetadataElement。其中,AttributeAccessor接口定义了最基本的对任意对象的元数据的修改或者获取,BeanMetadataElement接口提供了一个getResource()方法,用来传输一个可配置的源对象。(2)子接口:AnnotatedBeanDefinition。(3)子类: AbstractBeanDefinition、AnnotatedGenericBeanDefinition、ChildBeanDefinition、GenericBeanDefinition、RootBeanDefinition、ScannedGenericBeanDefinition。

7.20  BeanDefinitionCustomizer:定制一个给定的bean definition的回调函数,用在Lambda 表达式或者方法引用中。

7.21  BeanDefinitionHolder:使用名称或者别名来保存BeanDefinition。能够为内部bean做为占位符注册。

7.22  BeanDefinitionVisitor:遍历BeanDefinition对象的参观者类,特别是也遍历bean中的属性值和构造参数值,解析bean的元数据值。在PlaceholderConfigurerSupport中被使用,用来解析包含在BeanDefinition中全部的字符串值,解析发现的全部占位符。

 

7.23  BeanPostProcessor:容许对一个新的bean实例进行定制修改的工厂钩子。

7.24  BeanFactoryPostProcessor:容许对一个applicationContext中的bean definition进行定制修改的工厂钩子,修改context内含的bean factory中bean的属性值。

7.25  DestructionAwareBeanPostProcessor:BeanPostProcessor的子接口,它增长了一个销毁前回调方法。

7.26  InstantiationAwareBeanPostProcessor:BeanPostProcessor的子接口,它增长了一个初始化前回调方法,还有一个在初始化后但显式设置属性或者自动绑定发生前的回调方法。

7.27  InstantiationAwareBeanPostProcessorAdapter:实现了SmartInstantiationAwareBeanPostProcessor全部方法的适配器,它没有任何操做,不会改变容器对bean进行初始化的处理过程。

7.28  SmartInstantiationAwareBeanPostProcessor:InstantiationAwareBeanPostProcessor的扩展接口,它增长了对一个处理过bean的最终类型进行预测的回调方法。

 

7.29  CustomEditorConfigurer:继承自BeanFactoryPostProcessor,给自定义属性编辑器的注册提供了便利的方法。

7.30  CustomScopeConfigurer:BeanFactoryPostProcessor的简单实现,给自定义Scope的注册提供了便利的方法,上面提到ConfigurableBeanFactory提供了Scope的注册。

7.31  PreferencesPlaceholderConfigurer:PropertyPlaceholderConfigurer的子类,支持JDK1.4中的Preferences API (java.util.prefs)

7.32  PropertyOverrideConfigurer:属性资源配置器,它支持在applicationContext中重写一个bean的属性值。

7.33  PropertyPlaceholderConfigurer:PlaceholderConfigurerSupport的子类,它解析本地属性或者系统属性或者环境变量定义的占位符(以${}描述)。

7.34  PropertyResourceConfigurer:支持从一个属性资源中对单个bean的属性值进行配置。

 

7.35  BeanExpressionContext:计算一个BeanDefinition内部的表达式的容器对象。

7.36  BeanExpressionResolver:经过计算一个表达式来解析为值的策略接口。

7.37  EmbeddedValueResolver:StringValueResolver适配器,用于解析ConfigurableBeanFactory占位符和表达式。

7.38  BeanReference:暴露bean名称的引用接口。这个接口并不须要实际指向一个bean实例,只须要逻辑指向bean的名字。

7.39  RuntimeBeanNameReference:固定占位符类,当在beanfactory中做为另一个bean名称的引用时,做为属性值对象,将在运行时进行解析。

7.40  RuntimeBeanReference:固定占位符类,当在beanfactory中做为另一个bean的引用时,做为属性值对象,将在运行时进行解析。

7.41  TypedStringValue:保存一个类型的属性值。

7.42  ConstructorArgumentValues:保存构造方法的参数值,特别是做为Beandefinition的一部分。

7.43  DependencyDescriptor:将要注入的特定依赖的描述。

7.44  DeprecatedBeanWarner:继承自BeanFactoryPostProcessor,记录@Deprecated bean的报警信息。

7.45  PlaceholderConfigurerSupport:属性资源配置器的抽象基类,它解析BeanDefinition中属性值的占位符。

7.46  AutowiredPropertyMarker:简单的标记类,用于自动装载属性值,增长到BeanDefinition的getPropertyValues()函数为一个指定的bean 属性。

 

7.47  NamedBeanHolder:给定名字的bean实例的简单占位符。

7.48  SingletonBeanRegistry:定义了共享bean实例的注册接口。

7.49  Scope:ConfigurableBeanFactory使用的策略接口,表明了bean实例所在的做用域。Bean的做用域就是指Bean实例的生存空间或者有效范围。scope=[singleton, prototype, request, session, global session]

  一、singleton(单实例):在每一个Spring IOC容器中,一个Bean定义对应一个对象实例。这是Spring容器默认的做用域。当一个Bean的做用域为Singleton时,Spring IOC容器中只会存在一个共享的Bean实例,而且全部对Bean的请求,只要id与该Bean定义相匹配,就只会返回Bean的同一个实例。这个单一实例会被存储到单例缓存(Singleton Cache)中,而且全部针对该Bean的后续请求和引用都将返回被缓存的对象实例。单实例模式对于无会话状态的Bean(DAO组件、业务逻辑组件)来讲是理想的选择。

  二、prototype(原型模式):一个bean定义对应多个对象实例。prototype做用域的Bean在每次对该Bean请求时都会建立一个新的Bean实例,对须要保持会话状态的Bean(Struts2中充当控制器的Action类)应该使用prototype做用域。spring不能对一个原型模式Bean的整个生命周期负责,容器在初始化、装配好一个原型模式实例后,将它交给客户端,就再也不过问了。所以,客户端要负责原型模式实例的生命周期管理。

  三、request:在一次Http请求中,容器会返回该Bean的同一个实例,而对于不一样的用户请求,会返回不一样的实例。该做用域仅在基于Web的Spring ApplicationContext情形下有效。

  四、session:在一次HttpSession中,容器会返回该Bean的同一个实例。而对于不一样的HttpSession请求,会返回不一样的实例。该做用域仅在基于Web的Spring ApplicationContext情形下有效。

  五、global session:在全局的HTTPSession中,容器会返回该Bean的同一个实例。仅在使用portlet context时有效。

 

八、org.springframework.beans.factory.parsing包含的接口和类

8.1  AbstractComponentDefinition:ComponentDefinition接口的基本实现,提供了getDescription()来代理ComponentDefinition.getName()方法。

8.2  BeanComponentDefinition:基于一个标准BeanDefinition的ComponentDefinition,暴露指定bean的指定beanDefinition,内部BeanDefinition和BeanReference。

8.3  ComponentDefinition:描述在同一配置的Context中一组BeanDefinition和BeanReference的逻辑视图的接口。

8.4  CompositeComponentDefinition:保存了一个或者多个内嵌ComponentDefinition实例的ComponentDefinition实现,它把这些ComponentDefinition实例聚合成具备命名的组。

8.5  AliasDefinition:表明在解析进程中一个别名已经被注册。

8.6  ImportDefinition:在解析进程中,表明一个import已经被处理。

8.7  DefaultsDefinition:一个默认definition标识接口,继承了BeanMetadataElement,没有实现任何方法。

 

8.8  ConstructorArgumentEntry:表明了构造参数。

8.9  BeanEntry:表明了一个BeanDefinition。

8.10  PropertyEntry:表明了一个javaBean的属性。

8.11  QualifierEntry:表明了一个自动绑定的备选qualifier。

 

8.12  EmptyReaderEventListener:ReaderEventListener接口的空实现,全部回调方法都没有提供可执行操做。

8.13  ReaderEventListener:接受在读取BeanDefinition进程中注册组件、别名、import时的回调接口。

 

8.14  FailFastProblemReporter:ProblemReporter接口的简单实现,当遇到错误发生时展现fail-fast行为。

8.15  ProblemReporter:SPI接口,支持tool或者外部进程处理在beanDefinition解析期间报出的错误或者异常。

 

8.16  PassThroughSourceExtractor:SourceExtractor的简单实现,它经过一个attachment来传递备选的源数据类型对象。

8.17  NullSourceExtractor:SourceExtractor接口的简单实现,返回null做为source元数据。

8.18  SourceExtractor:简单策略接口,容许工具控制source元数据关联到bean definition元数据。

 

8.19  Location:模型接口,一个资源位置的模型。

8.20  ParseState:在解析进程中做为一个简单的基于栈结构的追踪逻辑位置类。

8.21  Problem:表明了一个beanDefinition配置问题。

8.22  ReaderContext:bean definition读取进程中传递的一个Context,封装了全部相关的配置,包括状态。

8.23  BeanDefinitionParsingException:一个bean definition验证失败时抛出异常的异常类。

 

九、org.springframework.beans.factory.serviceloader包含的接口和类

9.1  AbstractServiceLoaderBasedFactoryBean:FactoryBean的抽象基类,它是操做JDK1.6 ServiceLoader的基础工具。

9.2  ServiceFactoryBean:暴露指定配置的服务类的基础服务的FactoryBean,经过JDK1.6 serviceLoader基础类来获取这些服务。

9.3  ServiceListFactoryBean:暴露配置的服务类的全部基础服务的FactoryBea,表现为一组服务对象,能够经过JDK1.6 serviceLoader基础类来获取这些服务。

9.4  ServiceLoaderFactoryBean:暴露指定配置服务类的JDK1.6 serviceLoader的FactoryBean。

十、org.springframework.beans.factory.support包含的接口和类

10.1  DefaultListableBeanFactory:是beans包中最核心的一个类,ListableBeanFactory接口和BeanDefinitionRegistry接口的默认实现:基于beanDefinition对象的一个成熟的beanFactory。BeanDefinitionRegistry(在此包中)提供了beanDefinition的管理。AbstractAutowireCapableBeanFactory(在此包中)实现属性的自动绑定功能。ConfigurableListableBeanFactory(在org.springframework.beans.factory.config包中)提供了对bean定义的分析和修改的便利方法,同时也提供了对单例的预实例化。

  Serializable接口是Java提供的序列化接口,是一个空接口,为对象提供标准的序列化和反序列化操做。它的源代码是public interface Serializable{},即什么都没有,是一个标识接口。在Java中的这个Serializable接口是给JVM看的,告诉JVM,我不作这个类的序列化了,你(JVM)给我序列化。当咱们让实体类实现此接口,实际上是告诉JVM此类能够被序列化,可被默认的序列化机制序列化。那什么是序列化,做用是什么?序列化就是将一个对象及其状态转换成字节码,保存起来(能够保存在数据库、内存、文件等),而后能够在适当的时候再将其状态恢复(也就是反序列化)。有两个应用场景:一是想把内存中的对象状态保存到一个文件或者数据库中,二是想将对象经过网络进行传输的时候。

  DefaultListableBeanFactory是经过实现上述4个特定的功能的接口、抽象类来完成的,是一个成熟的bean factory。spring IOC容器的实现,从根源上是beanfactory,但真正能够做为一个独立使用的IOC容器仍是DefaultListableBeanFactory,所以能够说DefaultListableBeanFactory是整个spring IOC的始祖。它能够做为一个单独的BeanFactory,也可做为自定义BeanFactory的父类。其继承关系以下图:

  (1)类入口处提供了一个静态方法:

javaxInjectProviderClass=ClassUtils.forName("javax.inject.Provider",DefaultListableBeanFactory.class.getClassLoader());

  ClassUtils(在包org.springframework.util里)提供了对类的实用方法,主要用在框架内部。这个静态方法返回了javax.inject.Provider的一个实例。  包 javax.inject 指定了获取对象的一种方法,该方法与构造器、工厂这些传统方法相比能够得到更好的可重用性、可测试性以及可维护性。此方法的处理过程就是你们熟知的依赖注入。javax.inject.Provider其语法:public interface Provider,提供了一个T的实例,一般做为一个依赖注入容器的父接口,能够注入任何类型的T,固然也能够注入Provider,相对于直接注入,有几个好处:检索多个实例,延迟或者选择性的检索一个实例,打破循环依赖,抽象的scope,能够从一个包含scope的更小的scope中检索一个实例。

  (2)继承自AbstractAutowireCapableBeanFactory的方法

  提供bean的建立(有construct方法),属性注值,绑定(包括自动绑定)和初始化。处理运行时bean引用,解析管理的集合,调用初始化方法。

  最主要的实现的模板方法是:AutowireCapleBeanFactory类(在包org.springframework.beans. factory.config中,AbstractAutowireCapableBeanFactory实现此接口)中的方法resolveDependency(DependencyDescriptor, String, Set, TypeConverter)。这个方法用来实现类型的自动绑定AbstractAutowireCapableBeanFactory.copyConfigurationFrom(ConfigurableBeanFactory otherFactory)

  (3)继承自ListableBeanFactory接口的方法

  ListableBeanFactory(在包org.springframework.beans.factory中)是beanFactory接口的扩展接口,它能够枚举全部的bean实例,而不是客户端经过名称一个一个的查询得出全部的实例。要预加载全部的bean定义的beanfactory能够实现这个接口来。该接口定义了访问容器中Bean基本信息的若干方法,如查看Bean的个数、获取某一类型Bean的配置名、查看容器中是否包括某一Bean等方法;

继承自该接口的方法有:containsBeanDefinition()、findAnnotationOnBean() 、getBeanDefinitionCount() 、getBeanDefinitionNames()、getBeanNamesForType() 、getBeansOfType() 、getBeansWithAnnotation() 。

  (4)继承自ConfigurableListableBeanFactory接口的方法

  ConfigurableListableBeanFactory(在包org.springframework.beans.factory.config中)同时继承了ListableBeanFactory,AutowireCapableBeanFactory和ConfigurableBeanFactory,提供了对bean定义的分析和修改的便利方法,同时也提供了对单例的预实例化。

  继承该接口的方法有:freezeConfiguration() 、getBeanDefinition()、ignoreDependencyInterface() 、ignoreDependencyType() 、isAutowireCandidate() 、isConfigurationFrozen() 、preInstantiateSingletons()、registerResolvableDependency() 。

  (5)继承自BeanDefinitionRegistry接口的方法

  BeanDefinitionRegistry:Spring配置文件中每个节点元素在Spring容器里都经过一个BeanDefinition对象表示,它描述了Bean的配置信息。而BeanDefinition Registry接口提供了向容器手工注册BeanDefinition对象的方法。

  继承该接口的方法有:containsBeanDefinition() 、getBeanDefinition()、getBeanDefinitionCount()、getBeanDefinitionNames() 、isBeanNameInUse() 、registerBeanDefinition() 、removeBeanDefinition() 。

  (6)序列化支持

  private void writeObject(java.io.ObjectOutputStream out);

  private void readObject(java.io.ObjectInputStream in);

  private void readObjectNoData()。

10.2  StaticListableBeanFactory:静态BeanFactory的实现,用来编程实现注册已经存在的单例实例。

10.3  AbstractBeanFactory:BeanFactory的抽象基类实现,提供ConfigurableBeanFactory SPI的所有功能。

  在此简单介绍下SPI机制。SPI全称Service Provider Interface,一种服务发现机制。是Java提供的一套用来被第三方实现或者扩展的接口,它能够用来启用框架扩展和替换组件。SPI的做用就是为这些被扩展的API寻找服务实现。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。能够在运行时,动态为接口替换实现类。能够很容易的经过 SPI 机制为程序提供拓展功能。

10.4  AbstractAutowireCapableBeanFactory:抽象beanFactory的超类,它使用指定的RootBeanDefinition类的全部方法实现建立默认bean。

 

10.5  AbstractBeanDefinition:具体、成熟BeanDefinition类的基类,构造出RootBeanDefinition和ChildBeanDefinition的通用属性。

10.6  RootBeanDefinition:根BeanDefinition,表示在运行时期的spring BeanFactory中一个合并的BeanDefinition。

10.7  ChildBeanDefinition:从父类继承各类设置的bean的beanDefinition。

10.8  GenericBeanDefinition:通用BeanDefinition是一站式的标准bean Definition。

10.9  BeanDefinitionReader:bean definition解析器的简单接口。

10.10  BeanDefinitionReaderUtils:BeanDefinitionReader实现使用的工具方法类。

10.11  AbstractBeanDefinitionReader:实现了BeanDefinitionReader接口,是beanDefinitionReader的抽象基类。

10.12  PropertiesBeanDefinitionReader:简单属性格式的BeanDefinitionReader。

10.13  BeanDefinitionDefaults:简单保持BeanDefinition的默认属性类。

10.14  BeanDefinitionBuilder:使用建造者模式构建BeanDefinition的编程方法。

10.15  BeanDefinitionRegistry:持有beanDefinition的注册接口,例如RootBeanDefinition和ChildBeanDefinition实例。

10.16  SimpleBeanDefinitionRegistry:BeanDefinitionRegistry接口的简单实现。

10.17  BeanDefinitionRegistryPostProcessor:标准BeanFactoryPostProcessor SPI的扩展接口,容许在常规BeanFactoryPostProcessor检查以前注册更多bean definition。

10.18  BeanDefinitionResource:继承自AbstractResource,描述BeanDefinition的资源。在此介绍一下Spring使用的一种设计模式:装饰器模式。装饰器模式容许向一个现有的对象添加新的功能,同时又不改变其结构。装饰者能够在所委托被装饰者的行为以前或以后加上本身的行为,以达到特定的目的(如:功能的加强)。

10.19  BeanDefinitionValueResolver:主要用在bean工厂实施中,解析bean definition对象中的value,根据目标bean实例转换成真正的值。

10.20  BeanDefinitionValidationException:验证一个bean definition时出错抛出的异常。

10.21  BeanDefinitionOverrideException:BeanDefinitionStoreException一个子类,显示一个在尝试一个非法的重载。好比为同一个bean name注册一个新的definition,可是DefaultListableBeanFactory的isAllowBeanDefinitionOverriding却为false的时候。

                 

10.22  ManagedArray:集合类,用来保存它所管理的array元素,它能够包含运行时期的bean引用(将被解析为bean对象)。

10.23  ManagedList:集合类,用来保存它所管理的List元素,它能够包含运行时期的bean引用(将被解析为bean对象)。

10.24  ManagedMap:集合类,用来保存它所管理的array值,它能够包含运行时期的bean引用(将被解析为bean对象) 。

10.25  ManagedSet:集合类,用来保存它所管理的set值,它能够包含运行时期的bean引用(将被解析为bean对象) 。

10.26  ManagedProperties:表示一个spring管理的属性实例,它支持父/子 definition的合并。

       

10.27  AutowireCandidateQualifier:解析自动绑定备选项Qualifier。

10.28  AutowireCandidateResolver:策略接口,对特定的依赖,这个接口决定一个特定的bean definition是否知足做为自动绑定的备选项。

10.29  SimpleAutowireCandidateResolver:继承自AutowireCandidateResolver,当出现不支持的注解时使用。

10.30  GenericTypeAwareAutowireCandidateResolver:继承自SimpleAutowireCandidateResolver,一个通用的AutowireCandidateResolver。

10.31  AutowireUtils:工具类,为具备自动装载能力的bean工厂提供一些有用的方法。

 

10.32  LookupOverride:表示能够重写一个在同一个IOC上下文中查找对象的方法。

10.33  MethodOverride:表示重写对象,它针对IOC容器所管理对象的方法的重写。

10.34  MethodOverrides:一组方法重写,决定了在运行时期对spring IOC容器管理对象的重写方法(若是存在的话)。

10.35  ReplaceOverride:MethodOverride的扩展,表示一个IOC容器方法的任意重写。

 

10.36  InstantiationStrategy:负责根据相应的根bean definition建立实例的接口。

10.37  SimpleInstantiationStrategy:BeanFactory中简单对象的初始化策略。

10.38  CglibSubclassingInstantiationStrategy:BeanFactory默认对象初始化策略。

 

10.39  BeanNameGenerator:对beanDefinition产生bean名称的策略接口。

10.40  DefaultBeanNameGenerator:BeanNameGenerator接口的默认实现,代理BeanDefinitionReaderUtils.generateBeanName(BeanDefinition, BeanDefinitionRegistry)方法。

10.41  SecurityContextProvider:运行在beanFactory中的安全Context的提供者。

10.42  SimpleSecurityContextProvider:SecurityContextProvider的简单扩展。

10.43  DefaultSingletonBeanRegistry:共享bean实例的通用注册,实现了SingletonBeanRegistry。

10.44  FactoryBeanRegistrySupport:一个支持单例注册(须要处理FactoryBean实例)的基类,集合了DefaultSingletonBeanRegistry对单例的管理功能。

10.45  ConstructorResolver:解析构造函数和工程方法的代理。对构造函数的解析主要经过参数匹配来实现。

10.46  DisposableBeanAdapter:对一个给定的bean实例进行销毁bean及进行销毁的相关工做的适配器。

  这里简单介绍适配器模式:适配器就是为了实现接口而作的,若是不用适配器,你去实现接口的话,须要实现接口中的全部方法,这要那个就会带来一些麻烦,可是若是你使用了适配器,就能够定义一个类去实现接口,而后当你用哪一个方法的时候直接继承该类就好了,这个类就是适配器了。适配器模式的意义是要将一个接口转变成另外一个接口,它的目的是经过改变接口来达到重复使用的目的。而装饰器模式不是要改变被装饰对象的接口,而是偏偏要保持原有的接口,可是加强原有对象的功能,或者改变原有对象的处理方式而提高性能。

10.47  MethodReplacer:一个能够从新定义IOC容器对象的全部方法的接口:方法注入是依赖注入的一种形式。

10.48  MergedBeanDefinitionPostProcessor:后处理回调接口,在运行时合并bean definition。

10.49  NullBean:一个空bean的内部表示,好比调用FactoryBean的getObect()或者其余的工厂方法返回的是null值。

10.50  ImplicitlyAppearedSingletonException:继承自IllegalStateException,一个内部使用的异常类,在ConstructorResolver引起,传递给初始化DefaultSingletonBeanRegistry。

十一、org.springframework.beans.factory.wiring包含的接口和类

11.1  BeanConfigurerSupport:配置bean的便利基类,它能够对对象进行依赖注入。典型应用就是做为切面的子类使用。

11.2  BeanWiringInfo:保存特定类的bean的绑定元数据信息。在对注解和切面进行链接时使用。

11.3  BeanWiringInfoResolver:策略接口,可以根据给定的一个新初始化的bean对象解析bean的名称信息。在此简单介绍下策略模式:用意是针对一组算法,将每个算法封装到具备共同接口的独立类中,从而使得它们能够相互替换。策略模式使得算法能够在不影响到客户端的状况下发生变化。通俗的讲就是遇到一种问题有多种解法的时候,咱们能够根据环境或者条件的不一样选择不一样的算法或者策略来完成该功能。

11.4  ClassNameBeanWiringInfoResolver:BeanWiringInfoResolver的简单默认实现,查找一个和全限定名同名的bean的名称。

十二、org.springframework.beans.factory.xml包含的接口和类

12.1  AbstractBeanDefinitionParser:BeanDefinitionParser的抽象实现,提供了许多便利方法和模板方法,模板方法须要在子类进行重写来提供具体的逻辑实现。

12.2  AbstractSimpleBeanDefinitionParser:AbstractBeanDefinitionParser的简单实现,当将要解析元素的属性名和配置类的属性名一一对应的时候,能够用到该类。

12.3  AbstractSingleBeanDefinitionParser:BeanDefinitionParser的基类,须要解析和定义单独的BeanDefinition。

12.4  BeanDefinitionDecorator:DefaultBeanDefinitionDocumentReader用来处理自定义的,内嵌的标签的接口 。

12.5  BeanDefinitionDocumentReader:解析包含spring BeanDefinition的xml文件的SPI。

12.6  DefaultBeanDefinitionDocumentReader:BeanDefinitionDocumentReader接口的默认实现。

12.7  BeanDefinitionParser:DefaultBeanDefinitionDocumentReader用来处理自定义的,高层的标签的接口 。

12.8  BeanDefinitionParserDelegate:状态代理类,用来解析xml BeanDefinition。

       

12.9  BeansDtdResolver:spring bean dtd解析器EntityResolver的实现,用来从classpath或者jar文件加载dtd。

  DTD(Documnet Type Definition)即文档类型定义,是一种XML约束模式语言,是XML文件的验证机制,属于XML文件组成的一部分。DTD 是一种保证XML文档格式正确的有效方法,能够经过比较XML文档和DTD文件来看文档是否符合规范,元素和标签使用是否正确。

  XSD(XML Schemas Definition)XML Schema语言也就是XSD。XML Schema描述了XML文档的结构。能够用一个指定的XML Schema来验证某个XML文档,以检查该XML文档是否符合其要求。文档设计者能够经过XML Schema指定一个XML文档所容许的结构和内容,并可据此检查一个XML文档是不是有效的。XML Schema自己是一个XML文档,它符合XML语法结构。能够用通用的XML解析器解析它。

  XSD和DTD相比:DTD是使用非XML语法编写的,不可扩展,不支持命名空间,只提供很是有限的数据类型。XSD可跟据未来的条件可扩展,比DTD丰富和有用,用XML书写,支持数据类型,支持命名空间。

12.10  DefaultNamespaceHandlerResolver:NamespaceHandlerResolver接口的默认实现。

12.11  DelegatingEntityResolver:EntityResolver的实现,分别代理了dtd的BeansDtdResolver和xml schemas的 PluggableSchemaResolver。

12.12  NamespaceHandlerResolver:DefaultBeanDefinitionDocumentReader用来定位NamespaceHandler的接口。

12.13  PluggableSchemaResolver:继承自EntityResolver,使用一系列map文件将schema url解析到本地classpath资源。

12.14  ResourceEntityResolver:继承自EntityResolver,经过ResourceLoader来解析实体的引用。

 

12.15  XmlBeanDefinitionReader:Bean definition reader for XML bean definitions。

12.16  XmlBeanDefinitionStoreException:继承自BeanDefinitionStoreException。

12.17  XmlBeanFactory:过时,从spring 3.2 后推荐使用DefaultListableBeanFactory和XmlBeanDefinitionReader来代替它。

12.18  XmlReaderContext:ReaderContext的扩展,通常和XmlBeanDefinitionReader一块儿使用。

 

12.19  NamespaceHandler:实现了特定的URI命名空间。

12.20  NamespaceHandlerSupport:支持实现自定义的NamespaceHandler。

12.21  SimpleConstructorNamespaceHandler:单NamespaceHandler实现,它将自定义属性直接映射到bean属性。

12.22  SimplePropertyNamespaceHandler:简单NamespaceHandler实现,它将自定义属性直接映射到bean属性。

12.23  UtilNamespaceHandler:工具命名空间的NamespaceHandler。

 

12.24  DocumentDefaultsDefinition:简单的javaBean,它保存标准的spring xml文件中级别的属性,如:default-lazy-init,default-autowire等等。

12.25  DocumentLoader:加载xml文件的策略接口。

12.26  DefaultDocumentLoader:spring 的DocumentLoader默认实现。

12.27  ParserContext:传递一个beanDefinition 解析进程到此上下文,封装了全部的相关配置也包括状态。

 

3、BeanDefinition解析

  其实Spring的org.springframework.beans包下面全部的类主要解决了三件事情:Bean的定义,Bean的建立,Bean的解析。对于使用者来讲,惟一须要关心的就是Bean的建立,其余两个由Spring在内部帮你完成,对用户来讲是透明的。

  Bean的定义就是完整的描述了在Spring的配置文件中你定义节点中全部的信息,包括各类子节点。Bean的定义主要由BeanDefinition描述。当Spring成功解析你定义的节点后,在Spring的内部就被转换成BeanDefinition对象,之后全部的操做都是对这个对象完成的。

(一)BeanDefinition是什么?

  BeanDefinition 描述了一个Bean实例,它包含了Bean 的属性值,构造器参数,同时包含有更多其余的建立这个Bean的信息。更通俗点来说:BeanDefinition包含了创造一个Bean所须要的全部信息,属性,构造函数参数以及访问它们的方法,是一个Bean的元数据。

BeanDefinition在Spring中是用来描述Bean对象的,其自己不是一个bean实例,仅仅是包含bean实例的全部信息,好比属性值、构造器参数以及其余信息。Bean对象建立是根据BeanDefinition中描述的信息来建立的,BeanDefinition存在的做用是为了能够方便的进行修改属性值和其余元信息,好比经过BeanFactoryPostProcessor进行修改一些信息,而后在建立Bean对象的时候就能够结合原始信息和修改后的信息建立对象了。

(二)BeanDefinition属性

  在讲BeanDefinition的属性以前,咱们先一块儿看看BeanDefinition的继承体系。以下图,BeanDefinition继承图:

 

下面咱们看看BeanDefinition的属性:

  (1)id:Bean 的惟一标识名。它必须是合法的 XMLID,在整个 XML 文档中惟一。

  (2)name:用来为 id 建立一个或多个别名。它能够是任意的字母符合。多个别名之间用逗号或空格分开。

  (3)class:用来定义类的全限定名(包名+类名)。只有子类 Bean 不用定义该属性。

  (4)parent:子类 Bean 定义它所引用它的父类 Bean。这时前面的 class 属性失效。子类 Bean 会继承父类 Bean 的全部属性,子类 Bean 也能够覆盖父类 Bean 的属性。注意:子类 Bean 和父类 Bean 是同一个 Java 类。

  (5)abstract(默认为”false”):用来定义 Bean 是否为抽象 Bean。它表示这个 Bean 将不会被实例化,通常用于父类 Bean,由于父类 Bean 主要是供子类 Bean 继承使用。

  (6)lazy-init(默认为“default”):用来定义这个 Bean 是否实现懒初始化。若是为“true”,它将在 BeanFactory 启动时初始化全部的 SingletonBean。反之,若是为“false”,它只在 Bean 请求时才开始建立 SingletonBean。

  (7)autowire(自动装配,默认为“default”):它定义了 Bean 的自动装载方式。“no”:不使用自动装配功能。”byName”:经过 Bean 的属性名实现自动装配。”byType”:经过 Bean 的类型实现自动装配。“constructor”:相似于 byType,但它是用于构造函数的参数的自动组装。“autodetect”:经过 Bean 类的检讨机制(introspection)决定是使用“constructor”仍是使用“byType”。

  (8)depends-on(依赖对象):这个 Bean 在初始化时依赖的对象,这个对象会在这个 Bean 初始化以前建立。

  (9)init-method:用来定义 Bean 的初始化方法,它会在 Bean 组装以后调用。它必须是一个无参数的方法。

  (10)destroy-method:用来定义 Bean 的销毁方法,它在 BeanFactory 关闭时调用。一样,它也必须是一个无参数的方法。它只能应用于 singletonBean。

  (11)factory-method:定义建立该 Bean 对象的工厂方法。它用于下面的“factory-bean”,表示这个 Bean 是经过工厂方法建立。此时,“class”属性失效。

  (12)factory-bean:定义建立该 Bean 对象的工厂类。若是使用了“factory-bean”则“class”属性失效。

  (13)autowire-candidate:采用 xml 格式配置 bean 时,将元素的 autowire-candidate属性设置为 false,这样容器在查找自动装配对象时,将不考虑该 bean,即它不会被考虑做为其它 bean自动装配的候选者,可是该 bean 自己仍是能够使用自动装配来注入其它 bean 的。

  (14)MutablePropertyValues:用于封装标签的信息,其实类里面就是有一个 list,list里面是 PropertyValue 对象,PropertyValue 就是一个 name 和 value 属性,用于封装标签的名称和值信息。

  (15)ConstructorArgumentValues:用于封装标签的信息,其实类里面就是有一个 map,map 中用构造函数的参数顺序做为 key,值做为 value 存储到 map 中。

  (16)MethodOverrides:用于封装 lookup-method 和 replaced-method 标签的信息,一样的类里面有一个 Set 对象添加 LookupOverride 对象和 ReplaceOverride 对象。

(三)BeanDefinition实现类

  bean definition的实现类共有三个,分别为ChildBeanDefinition,RootBeanDefinition,GenericBeanDefinition。

  一、ChildBeanDefinition:是一种bean definition,它能够继承它父类的设置,即ChildBeanDefinition对RootBeanDefinition有必定的依赖关系。ChildBeanDefinition从父类继承构造函数参数值、属性值,并能够重写父类的方法,同时也能够增长新的属性或者方法。若指定初始化方法、销毁方法或者静态工厂方法,ChildBeanDefinition将重写相应父类的设置。depends on、 autowire mode、dependency check、singleton、lazy int通常由子类自行设定。

  二、RootBeanDefinition:一个RootBeanDefinition定义代表它是一个可合并的bean definition:即在spring beanFactory运行期间,能够返回一个特定的bean。RootBeanDefinition能够做为一个重要的通用的bean definition 视图。

  三、GenericBeanDefinition:能够有效替代ChildBeanDefinition的绝大部分使用场合。是一站式标准的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。

(四)BeanDefinition的载入和解析

  对于IOC容器来讲,这个载入过程,至关于把定义的BeanDefinition在IOC容器中转换成一个Spring内部表示的数据结构的过程。IOC容器对Bean的管理和依赖注入功能的实现,是经过对其持有的BeanDefinition进行各类操做来完成的。这些BeanDefinition数据在IOC容器中经过一个HashMap来保持和维护。

  一、下面从DefaultListableBeanFactory入手,看下IOC容器是怎样完成BeanDefinition载入的。在开始分析以前,先回到IOC容器初始化入口,也就是看一下refresh方法。这个方法的最初是在FileSystemXmlApplicationContext的构造函数中被调用的,它的调用标志着容器初始化的开始,这些初始化化对象就是BeanDefinition数据。对于容器启动来讲,refresh是一个很重要的方法。该方法在AbstractApplicationContext类(是FileSystemXMLApplicationContext的基类)中,它详细描述了整个ApplicationContext的初始化过程,好比BeanFactory的更新,MessageSource和PostProcessor的注册等等。这个执行过程为Bean的生命周期管理提供了条件。下面代码显示了对IOC容器执行refresh过程:

 1     public void refresh() throws BeansException, IllegalStateException {
 2         synchronized (this.startupShutdownMonitor) {
 3             // Prepare this context for refreshing.
 4             prepareRefresh();
 5             // 这里是在子类中启动refreshBeanFactory()的地方
 6             ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 7             // Prepare the bean factory for use in this context.
 8             prepareBeanFactory(beanFactory);
 9 
10             try {
11                 // 设置BeanFactory的后置处理
12                 postProcessBeanFactory(beanFactory);.
13                 // 调用BeanFactory的后处理器,这些后处理器是在Bean定义中向容器注册的
14                 invokeBeanFactoryPostProcessors(beanFactory);
15                 // 注册Bean的后处理器,在Bean建立过程当中调用
16                 registerBeanPostProcessors(beanFactory);
17                 // 对上下文中的消息源进行初始化
18                 initMessageSource();
19                 // 初始化上下文中的事件机制
20                 initApplicationEventMulticaster();
21                 // 初始化其余的特殊Bean
22                 onRefresh();
23                 // 检查监听Bean而且将这些Bean向容器注册
24                 registerListeners();
25                 // 实例化全部的(non-lazy-init)单件
26                 finishBeanFactoryInitialization(beanFactory);
27                 // 发布容器事件,结束Refresh过程
28                 finishRefresh();
29             }
30 
31             catch (BeansException ex) {
32                 if (logger.isWarnEnabled()) {
33                     logger.warn("Exception encountered during context initialization - " +
34                             "cancelling refresh attempt: " + ex);
35                 }
36                 // 为防止Bean资源占用,在异常处理中,销毁已经在前面过程当中生成的单件Bean
37                 destroyBeans();
38                 // 重置 'active'标志
39                 cancelRefresh(ex);
40                 // Propagate exception to caller.
41                 throw ex;
42             }
43 
44             finally {
45                 // Reset common introspection caches in Spring's core, since we
46                 // might not ever need metadata for singleton beans anymore...
47                 resetCommonCaches();
48             }
49         }
50     }

  二、进入到AbstractRefreshableAppliccationContext的refreshBeanFactroy()方法中,在这个方法中建立了BeanFactory。在建立IOC容器前,若是已经有容器存在,那么须要把已有的容器销毁和关系,保证refresh之后使用的都是新创建起来的IOC容器。

  三、当创建好了当前的IOC容器之后,开始了对容器的初始化,好比BeanDefinition的载入。以下图所示:

 

  这里调用的loadBeanDefinitions其实是一个抽象方法,loadBeanDefinitions在AbstractRefreshableApplicationContext的子类AbstractXmlApplicationContext中的实现,在这个loadBeanDefinitions中,初始化了读取器XMLBeanDefinitionReader,而后把这个读取器在IOC容器中设置好。最后是启动读取器来完成BeanDefinition在IOC容器中的载入。接着就是loadBeanDefinitions调用的地方,首先获得BeanDefinition信息的Resource定位,而后直接调用XMLBeanDefinitionReader来读取,具体的载入过程是委托给BeanDefinitionReader来完成的。由于这里的BeanDefinition是经过XML文件来定义的,因此这里使用XMLBeanDefinitionReader来载入BeanDefinition到容器中。

  四、经过以上对实现原理分析,在初始化FileSystemXmlApplicationContext的过程当中是经过调用IOC容器的refresh来启动整个BeanDefinition的载入过程的,这个初始化是经过定义的XmlBeanDefinitionReader来完成的。同时咱们知道实际使用IOC容器是DefaultListableBeanFactory,具体的Resource载入在XmlBeanDefinitionReader读入BeanDefinition时实现。由于Spring能够对应不一样形式的BeanDefinition。因为这里使用的是Xml方式的定义,全部须要使用XMLBeanDefinitionReader。若是使用了其余的BeanDefinition方式,就须要使用其余的BeanDefinitionReader来完成数据的载入工做。

 

4、Bean默认标签解析

  Spring的标签分为默认标签和自定义标签,Spring用节点的命名空间来判断是默认仍是自定义标签。若是节点的命名空间为http://www.Springframework.org/schema/beans就认为是默认标签,不然就认为是自定义标签。

(一)默认标签

  默认标签的解析在DefaultBeanDefinitionDocumentReader(在org.springframework.beans.factory.xml包中)类的parseDefaultElement方法中:

 1     private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
 2         if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
 3             importBeanDefinitionResource(ele);
 4         }
 5         else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
 6             processAliasRegistration(ele);
 7         }
 8         else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
 9             processBeanDefinition(ele, delegate);
10         }
11         else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
12             // recurse
13             doRegisterBeanDefinitions(ele);
14         }
15     }

  方法的逻辑很清晰,按默认标签是import、alias、bean、beans四类状况分别处理。其中,bean标签的解析最为复杂。

 

(二)bean标签的解析及注册(对应上述代码中processBeanDefinition(ele, delegate))

  在此先简单介绍下bean标签,该标签用于声明一个类,在启动 Spring 框架的时候根据该配置的类建立对象到容器里面。属性以下所示:

<bean>标签:用于声明一个类,在启动Spring框架的时候根据该配置的类建立对象到容器里面

        name:设置对象名(惟一标识符)

        id:设置对象名(惟一标识符,功能和name同样)

        class:用于指定对象对应的类名,若是不是实现类必需要将bean声明为抽象的!

        scope:用于设置的对象的做用范围,可选参数以下:

           *singleton:单例(默认)

               对象出生:当程序加载配置文件建立容器时,建立

               对象活着:只要容器还在,一直活着

               对象死亡:应用中止,容器销毁,对象死亡

           *prototype:多例(原型对象)

               对象出生:当程序加载配置文件建立容器时建立(每次调用会建立一个新对象)

               对象活着:只要对象被使用,一直活着

               对象死亡:对象长时间不用,会被Java垃圾回收机制回收 (该对象不被容器管理)

           *reqeust:web项目中,Spring将建立的对象放在request做用域中

           *session:web项目中,Spring将建立的对象放在session做用域中

       init-method:设置建立对象的时候,调用初始化方法

       destroy-method:设置对象被回收时,调用注销的方法

<bean name="customerServiceImpl" class="cn.mgy.service.impl.CustomerServiceImpl"></bean>

  首先咱们来看看processBeanDefinition(ele,delegate)方法,对bean标签的解析进行一个大体上的流程了解:

 1     /**
 2      * Process the given bean element, parsing the bean definition
 3      * and registering it with the registry.
 4      */
 5     protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
 6         BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
 7         if (bdHolder != null) {
 8             bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
 9             try {
10                 // Register the final decorated instance.
11                 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
12             }
13             catch (BeanDefinitionStoreException ex) {
14                 getReaderContext().error("Failed to register bean definition with name '" +
15                         bdHolder.getBeanName() + "'", ele, ex);
16             }
17             // Send registration event.
18             getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
19         }
20     }

对上述代码进行分析:

  一、BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement (ele);首先委托BeanDefinitionParserDelegate类(在org.springframework.beans. factory.xml包中)的parseBeanDefinitionElement()方法进行元素的解析,返回BeanDefinitionHolder类的实例bdHolder(return new BeanDefinitionHolder( beanDefinition, beanName, aliasesArray);)。方法调用完成后,bdHolder实例就包含咱们配置的各类属性了,例如:class、name、id、alias之类的属性。

  二、if (bdHolder != null)当返回的bdHolder不为空的状况下,若存在默认标签的子节点下面还有自定义的属性,还须要再次对自定义的标签进行解析。

  三、BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());解析完成后,须要对解析后的bdHolder进行注册,注册委托给了BeanDefinitionReaderUtils(在包org.springframework.beans.factory.support中)的registerBeanDefinition方法。

  四、getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));发出响应事件,通知相关的监听器,该bean加载完成。

 

(三)解析BeanDefinition(对应上述代码的BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele))

  下面详细分析下BeanDefinitionHolder bdHolder = delegate. parseBeanDefinitionElement(ele);,进入BeanDefinitionParserDelegate的parseBeanDefinitionElement()方法:

 1     /**
 2      * Parses the supplied {@code <bean>} element. May return {@code null}
 3      * if there were errors during parse. Errors are reported to the
 4      * {@link org.springframework.beans.factory.parsing.ProblemReporter}.
 5      */
 6     @Nullable
 7     public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
 8     /*********提取元素中的id以及name属性*********/
 9         //解析id属性
10         String id = ele.getAttribute(ID_ATTRIBUTE);
11         //解析name属性
12         String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
13         //分割name属性
14         List<String> aliases = new ArrayList<>();
15         if (StringUtils.hasLength(nameAttr)) {
16             //将name属性的值经过,; 进行分割 转为字符串数字(即在配置文件中如配置多个name在此作处理)
17             String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
18             aliases.addAll(Arrays.asList(nameArr));
19         }
20 
21         String beanName = id;
22         // 若是ID为空 使用配置的第一个name属性做为ID
23         if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
24             beanName = aliases.remove(0);
25             if (logger.isTraceEnabled()) {
26                 logger.trace("No XML 'id' specified - using '" + beanName +
27                         "' as bean name and " + aliases + " as aliases");
28             }
29         }
30 
31         if (containingBean == null) {
32             // 校验beanName和aliases的惟一性
33             // 内部核心为使用usedNames集合保存全部已经使用了的beanName和alisa
34             checkNameUniqueness(beanName, aliases, ele);
35         }
36     /*********进一步解析其余全部属性到GenericBeanDefinition对象中*********/
37         AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
38     /*********若是检测到Bean没有指定beanName,那么使用默认规则为此Bean生成对应的beanName*********/
39         if (beanDefinition != null) {
40             if (!StringUtils.hasText(beanName)) {
41                 try {
42                     if (containingBean != null) {
43                         beanName = BeanDefinitionReaderUtils.generateBeanName(
44                                 beanDefinition, this.readerContext.getRegistry(), true);
45                     }
46                     else {
47                         beanName = this.readerContext.generateBeanName(beanDefinition);
48                         // Register an alias for the plain bean class name, if still possible,
49                         // if the generator returned the class name plus a suffix.
50                         // This is expected for Spring 1.2/2.0 backwards compatibility.
51                         String beanClassName = beanDefinition.getBeanClassName();
52                         if (beanClassName != null &&
53                                 beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
54                                 !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
55                             aliases.add(beanClassName);
56                         }
57                     }
58                     if (logger.isTraceEnabled()) {
59                         logger.trace("Neither XML 'id' nor 'name' specified - " +
60                                 "using generated bean name [" + beanName + "]");
61                     }
62                 }
63                 catch (Exception ex) {
64                     error(ex.getMessage(), ele);
65                     return null;
66                 }
67             }
68             String[] aliasesArray = StringUtils.toStringArray(aliases);
69     /*********将获取到的信息封装到BeanDefinitionHolder的实例中*********/
70             return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
71         }
72 
73         return null;
74     }

  上述代码即是对默认标签解析的全过程。在对属性展开解析以前,Spring在外层又作了一个当前层的功能架构。重点看“进一步解析其余全部属性到GenericBeanDefinition对象中”,对应的代码为AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);,是一个重载函数,进入其代码:

 1     /**
 2      * Parse the bean definition itself, without regard to name or aliases. May return
 3      * {@code null} if problems occurred during the parsing of the bean definition.
 4      */
 5     @Nullable
 6     public AbstractBeanDefinition parseBeanDefinitionElement(
 7             Element ele, String beanName, @Nullable BeanDefinition containingBean) {
 8 
 9         this.parseState.push(new BeanEntry(beanName));
10         //解析class属性
11         String className = null;
12         if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
13             className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
14         }
15         //解析parent属性
16         String parent = null;
17         if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
18             parent = ele.getAttribute(PARENT_ATTRIBUTE);
19         }
20 
21         try {
22             //建立用于承载属性的AbstractBeanDefinition类型的GenericBeanDefinition
23             AbstractBeanDefinition bd = createBeanDefinition(className, parent);
24             //硬编码解析默认bean的各类属性
25             parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
26             //提取description
27             bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
28             //解析元数据
29             parseMetaElements(ele, bd);
30             //解析lookup-Method属性
31             parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
32             //解析replaced-method属性
33             parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
34             //解析构造函数参数
35             parseConstructorArgElements(ele, bd);
36             //解析property子元素
37             parsePropertyElements(ele, bd);
38             //解析qualifier子元素
39             parseQualifierElements(ele, bd);
40 
41             bd.setResource(this.readerContext.getResource());
42             bd.setSource(extractSource(ele));
43 
44             return bd;
45         }
46         catch (ClassNotFoundException ex) {
47             error("Bean class [" + className + "] not found", ele, ex);
48         }
49         catch (NoClassDefFoundError err) {
50             error("Class that bean class [" + className + "] depends on not found", ele, err);
51         }
52         catch (Throwable ex) {
53             error("Unexpected failure during bean definition parsing", ele, ex);
54         }
55         finally {
56             this.parseState.pop();
57         }
58 
59         return null;
60     }

 

(四)建立用于承载属性的GenericBeanDefinition(对应上述代码的AbstractBeanDefinition bd = createBeanDefinition(className, parent))

  BeanDefinition是一个接口,详见(3、BeanDefinition解析)。有三个对应它的实现:RootBeanDefinition、ChildBeanDefinition、GenericBeanDefinition。这三种实现均继承了AbstractBeanDefinition,其中BeanDefinition是配置文件元素标签在容器中的内部表示形式。元素有class、scope、lazy-init等配置属性。BeanDefinition则提供了相应的beanClass、scope、lazyInit属性,二者的属性是一一对应的。在配置文件中能够定义父和子,父用RootBeanDefinition表示,而子用ChildBeanDefinition表示,而没有父的就使用RootBeanDefinition表示。AbstractBeanDefinition对二者共同的类信息进行抽象。Spring经过BeanDefinition将配置文件中的配置信息转换为容器的内部表示,并将这些BeanDefinition注册到BeanDefinitionRegistry中。Spring容器的BeanDefinitionRegistry就像是Spring配置信息的内存数据库,主要以map形式进行保存,后续操做直接从BeanDefinitionRegistry中读取配置信息。要解析属性首先要建立用于承载属性的实例,也就是建立GenericBeanDefinition类型的实例。对应的代码为AbstractBeanDefinition bd = createBeanDefinition(className, parent),进入该函数:

 1     /**
 2      * Create a bean definition for the given class name and parent name.
 3      * @param className the name of the bean class
 4      * @param parentName the name of the bean's parent bean
 5      * @return the newly created bean definition
 6      * @throws ClassNotFoundException if bean class resolution was attempted but failed
 7      */
 8     protected AbstractBeanDefinition createBeanDefinition(@Nullable String className, @Nullable String parentName)
 9             throws ClassNotFoundException {
10 
11         return BeanDefinitionReaderUtils.createBeanDefinition(
12                 parentName, className, this.readerContext.getBeanClassLoader());
13     }

  继续跟踪下去:进入BeanDefinitionReaderUtils类(在包org.springframework.beans.factory.support中)中的函数:

 1     /**
 2      * Create a new GenericBeanDefinition for the given parent name and class name,
 3      * eagerly loading the bean class if a ClassLoader has been specified.
 4      * @param parentName the name of the parent bean, if any
 5      * @param className the name of the bean class, if any
 6      * @param classLoader the ClassLoader to use for loading bean classes
 7      * (can be {@code null} to just register bean classes by name)
 8      * @return the bean definition
 9      * @throws ClassNotFoundException if the bean class could not be loaded
10      */
11     public static AbstractBeanDefinition createBeanDefinition(
12             @Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {
13 
14         GenericBeanDefinition bd = new GenericBeanDefinition();
15         bd.setParentName(parentName);
16         // parentName可能为空
17         if (className != null) {
18             //若是classLoader不为空,则使用传入的classLoader同一虚拟机加载类对象
19             if (classLoader != null) {
20                 bd.setBeanClass(ClassUtils.forName(className, classLoader));
21             }
22             //不然只记录classLoader
23             else {
24                 bd.setBeanClassName(className);
25             }
26         }
27         return bd;
28     }

  至此createBeanDefinition() 已经解析完,并且咱们也得到了用于承载属性的AbstractBeanDefinition了。


(五)解析各类属性(对应(三)解析BeanDefinition中的代码 parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);)

  上述已经建立了bean信息的承载实例,接下来就能够进行bean信息的各类属性分析了。进入parseBeanDefinitionAttributes方法,此方法是对Element全部的元素属性进行分析。该方法也在类BeanDefinitionParserDelegate中。

 1     /**
 2      * Apply the attributes of the given bean element to the given bean * definition.
 3      * @param ele bean declaration element
 4      * @param beanName bean name
 5      * @param containingBean containing bean definition
 6      * @return a bean definition initialized according to the bean element attributes
 7      */
 8     public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
 9             @Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {
10         //scope和singleton两种属性只能指定其中之一,不能够同时出现,不然Spring会抛出异常
11         if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
12             error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
13         }
14         //解析scope属性
15         else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
16             bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
17         }
18         else if (containingBean != null) {
19             //在嵌入BeanDefinition状况下且没有单独指定scope属性则使用父类默认的属性
20             bd.setScope(containingBean.getScope());
21         }
22         //解析abstract属性
23         if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
24             bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
25         }
26         //解析lazy-init属性
27         String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
28         if (isDefaultValue(lazyInit)) {
29             lazyInit = this.defaults.getLazyInit();
30         }
31         //若没有设置或者设置成其余字符都会被设置为false
32         bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
33         //解析autowire属性
34         String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
35         bd.setAutowireMode(getAutowireMode(autowire));
36         //解析depends-on属性
37         if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
38             String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
39             bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
40         }
41         //解析autowire-candidate属性
42         String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
43         if (isDefaultValue(autowireCandidate)) {
44             String candidatePattern = this.defaults.getAutowireCandidates();
45             if (candidatePattern != null) {
46                 String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
47                 bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
48             }
49         }
50         else {
51             bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
52         }
53         //解析primary属性
54         if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
55             bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
56         }
57         //解析init-method属性
58         if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
59             String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
60             bd.setInitMethodName(initMethodName);
61         }
62         else if (this.defaults.getInitMethod() != null) {
63             bd.setInitMethodName(this.defaults.getInitMethod());
64             bd.setEnforceInitMethod(false);
65         }
66         //解析destroy-method属性
67         if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
68             String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
69             bd.setDestroyMethodName(destroyMethodName);
70         }
71         else if (this.defaults.getDestroyMethod() != null) {
72             bd.setDestroyMethodName(this.defaults.getDestroyMethod());
73             bd.setEnforceDestroyMethod(false);
74         }
75         //解析factory-method属性
76         if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
77             bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
78         }
79         //解析factory-bean属性
80         if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
81             bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
82         }
83 
84         return bd;
85     }

  在完成上面步骤后,也就是对bean全部的属性的解析后,将会把获取到的信息都封装到BeanDefinitionHolder中(在包org.springframework.beans.factory.config中)。查看其构造函数:

1 public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName, @Nullable String[] aliases) {
2     Assert.notNull(beanDefinition, "BeanDefinition must not be null");
3     Assert.notNull(beanName, "Bean name must not be null");
4     this.beanDefinition = beanDefinition;
5     this.beanName = beanName;
6     this.aliases = aliases;
7 }
  以上就是对bean标签的解析。

5、Bean的加载

  下面一段简单的代码能够做为Spring代码加载的入口:MyTestBean myTestBean = (MyTestBean) beanFactory.getBean("myTestBean");。Spring经过调用BeanFactory的getBean()方法来加载bean。getBean()方法的真正实如今类AbstractBeanFactory中(在org.springframework.beans.factory.support包中),看下该方法的源码:

  1     /**
  2      * Return an instance, which may be shared or independent, of the specified bean.
  3      * @param name the name of the bean to retrieve
  4      * @param requiredType the required type of the bean to retrieve
  5      * @param args arguments to use when creating a bean instance using explicit arguments
  6      * (only applied when creating a new instance as opposed to retrieving an existing one)
  7      * @param typeCheckOnly whether the instance is obtained for a type check,
  8      * not for actual use
  9      * @return an instance of the bean
 10      * @throws BeansException if the bean could not be created
 11      */
 12     @SuppressWarnings("unchecked")
 13     protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
 14             @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
 15     /***************************(1)转换对应的beanName ***************************/
 16         // 提取对应的bean名称
 17         final String beanName = transformedBeanName(name);
 18         Object bean;
 19     /***************************(2)尝试从缓存中加载单例 **************************/
 20         // 检查缓存中或者实例工厂中是否有对应的实例,直接尝试从缓存中获取或者singletonFactories中的ObjectFactory中获取
 21         // 为何会首先使用这段代码?
 22         // 由于在建立单例bean的时候会存在依赖注入的状况,而在建立依赖的时候为了不循环依赖
 23         // Spring建立bean的原则是不等bean建立完成就会将建立bean的ObjectFactory提前曝光
 24         // 也就是将ObjectFactory加入到缓存中,一旦下个bean建立的时候须要依赖上个bean则直接使用ObjectFactory
 25         Object sharedInstance = getSingleton(beanName);
 26         if (sharedInstance != null && args == null) {
 27             if (logger.isTraceEnabled()) {
 28                 if (isSingletonCurrentlyInCreation(beanName)) {
 29                     logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
 30                             "' that is not fully initialized yet - a consequence of a circular reference");
 31                 }
 32                 else {
 33                     logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
 34                 }
 35             }
 36     /******************************(3)bean的实例化 ******************************/
 37             // 若是从缓存中获得了bean的原始状态,则须要对bean进行实例化。
 38             // 有时候存在诸如BeanFactory的状况并非直接返回实例自己而是返回指定方法返回的实例
 39             bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
 40         }
 41         // 缓存中取不到
 42         else {
 43             // 只有在单例状况下才会尝试解决循环依赖;
 44             // 原型模式状况下,若是存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未建立完的时候由于
 45             // 对于B的建立再次返回到建立A,形成循环依赖,也就是下面的状况。对于“prototype”做用域Bean,Spring容器没法完成依赖注入,
 46             // 由于“prototype”做用域的Bean,Spring容器不进行缓存,所以没法提早暴露一个建立中的Bean。
 47     /**********************(4)原型模式(prototype)的依赖检查 **********************/
 48             if (isPrototypeCurrentlyInCreation(beanName)) {
 49                 throw new BeanCurrentlyInCreationException(beanName);
 50             }
 51     /*************************(5)检测parentBeanFactory **************************/
 52             //确认是否存在父类工厂
 53             BeanFactory parentBeanFactory = getParentBeanFactory();
 54             //若父类不为空而且BeanDefinitionMap中全部加载的类不包括beanName,则尝试在父类工厂去检测
 55             if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
 56                 // Not found -> check parent.
 57                 String nameToLookup = originalBeanName(name);
 58                 if (parentBeanFactory instanceof AbstractBeanFactory) {
 59                     return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
 60                             nameToLookup, requiredType, args, typeCheckOnly);
 61                 }
 62                 else if (args != null) {
 63                     // 委托给具备显示参数args的父工厂,递归到BeanFactory中寻找
 64                     return (T) parentBeanFactory.getBean(nameToLookup, args);
 65                 }
 66                 else if (requiredType != null) {
 67                     //委托给标准的父工厂getBean方法
 68                     return parentBeanFactory.getBean(nameToLookup, requiredType);
 69                 }
 70                 else {
 71                     return (T) parentBeanFactory.getBean(nameToLookup);
 72                 }
 73             }
 74 
 75             // 若是不只仅是作类型检查而是建立bean,在这里进行记录
 76             if (!typeCheckOnly) {
 77                 markBeanAsCreated(beanName);
 78             }
 79 
 80             try {
 81     /***************(6)GenericBeanDefinition转为RootBeanDefinition **************/
 82                 // 将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition,
 83                 // 若是指定BeanName是子Bean的话同时会合并父类的相关属性
 84                 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
 85                 checkMergedBeanDefinition(mbd, beanName, args);
 86     /*********************************(7)寻找依赖 *******************************/
 87                 //获得该bean所依赖的相关bean
 88                 String[] dependsOn = mbd.getDependsOn();
 89                 // 若存在依赖则须要递归实例化依赖的bean
 90                 if (dependsOn != null) {
 91                     for (String dep : dependsOn) {
 92                         if (isDependent(beanName, dep)) {
 93                             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 94                                     "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
 95                         }
 96                         // 缓存依赖调用
 97                         registerDependentBean(dep, beanName);
 98                         try {
 99                             getBean(dep);
100                         }
101                         catch (NoSuchBeanDefinitionException ex) {
102                             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
103                                     "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
104                         }
105                     }
106                 }
107     /*********************(8)依据scope建立bean(最关键的一步) ********************/
108                 //到这里已经实例化玩依赖的bean了,因此开始实例化mbd自己了
109                 // singleton模式的建立
110                 if (mbd.isSingleton()) {
111                     sharedInstance = getSingleton(beanName, () -> {
112                         try {
113                             return createBean(beanName, mbd, args);
114                         }
115                         catch (BeansException ex) {
116                             // Explicitly remove instance from singleton cache: It might have been put there
117                             // eagerly by the creation process, to allow for circular reference resolution.
118                             // Also remove any beans that received a temporary reference to the bean.
119                             destroySingleton(beanName);
120                             throw ex;
121                         }
122                     });
123                     bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
124                 }
125 
126                 else if (mbd.isPrototype()) {
127                     // prototype原型模式的建立(new)
128                     Object prototypeInstance = null;
129                     try {
130                         beforePrototypeCreation(beanName);
131                         prototypeInstance = createBean(beanName, mbd, args);
132                     }
133                     finally {
134                         afterPrototypeCreation(beanName);
135                     }
136                     bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
137                 }
138 
139                 else {
140                     // 指定的scope上实例化bean
141                     String scopeName = mbd.getScope();
142                     final Scope scope = this.scopes.get(scopeName);
143                     if (scope == null) {
144                         throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
145                     }
146                     try {
147                         Object scopedInstance = scope.get(beanName, () -> {
148                             beforePrototypeCreation(beanName);
149                             try {
150                                 return createBean(beanName, mbd, args);
151                             }
152                             finally {
153                                 afterPrototypeCreation(beanName);
154                             }
155                         });
156                         bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
157                     }
158                     catch (IllegalStateException ex) {
159                         throw new BeanCreationException(beanName,
160                                 "Scope '" + scopeName + "' is not active for the current thread; consider " +
161                                 "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
162                                 ex);
163                     }
164                 }
165             }
166             catch (BeansException ex) {
167                 cleanupAfterBeanCreationFailure(beanName);
168                 throw ex;
169             }
170         }
171     /*********************************(9)类型转换 *******************************/
172         // 检查须要的类型是否符合bean的实际类型
173         if (requiredType != null && !requiredType.isInstance(bean)) {
174             try {
175                 T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
176                 if (convertedBean == null) {
177                     throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
178                 }
179                 return convertedBean;
180             }
181             catch (TypeMismatchException ex) {
182                 if (logger.isTraceEnabled()) {
183                     logger.trace("Failed to convert bean '" + name + "' to required type '" +
184                             ClassUtils.getQualifiedName(requiredType) + "'", ex);
185                 }
186                 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
187             }
188         }
189         return (T) bean;
190     }

上述1-9步在上述代码中已用分割线隔开,下面依次进行分析:
  (1)转换对应的beanName转换对应的 beanName 是根据 getBean(String name) 方法传入的 name 参数进行的,传入的 name 并不必定是 beanName,多是别名,也多是 FactoryBean 。因为 name 的多种可能,Spring会进行对应的转换。这些转换包括: 1)去除 FactoryBean 的修饰符,通常就是去除 name 参数的 & 前缀;2)取指定的 alias 所表示的最终 beanName,例如别名 A 指向别名 B,别名 B 指向名称为 C 的 bean,则最后返回 C。实际是由org.springframework.beans.factory包中的BeanFactoryUtils类中的函数transformedBeanName()完成此功能。

  (2)尝试从缓存中加载单例单例在Spring中的同一个容器内只会被建立一次,后续再获取 bean就直接从单例缓存中获取了。固然代码实现上首先进行尝试从缓存中进行加载,若是不成功再尝试从 singletonFactories 中加载,最后都不行才判断是没有建立过继而新建并放入缓存。之因此须要从 singletonFactories 中加载,由于在建立单例 bean 的时候会存在依赖注入 的状况,而在建立依赖 bean 的时候,为了不循环依赖,Spring中建立 bean 的原则是不等 bean 建立完成就会提早将建立 bean 的 ObjectFactory 曝光加入到缓存中,一旦下一个 bean 建立的时候须要依赖该 bean 时则能够直接使用 ObjectFactory 做为依赖进行注入。

  (3)bean的实例化若是从缓存中获得了 bean 的原始状态,则须要对 bean 进行实例化。缓存中记录的只是最原始的 bean 状态,并非咱们最终想要的 bean。例如:假如咱们须要对工厂 bean 进行处理,那么这里获得的实际上是工厂 bean 的初始状态,但咱们真正须要的是工厂 bean 中定义的 factory-method方法中返回的 bean,而 getObjectForBeanInstance(sharedInstance, name, beanName, null) 就是完成这项工做。

  (4)原型模式(prototype)的依赖检查Spring可以尝试解决的循环依赖问题只有单例模式下,对于原型模式的循环依赖问题Spring是没有方法解决的。由于在原型模式(prototype)下,若是 A 依赖 B,B 同时又依赖 A,那么就会出现建立 A 时由于建立依赖 B 而又要建立 A ,由于是多例的,因此会一直循环建立。Spring对于原型模式下的循环依赖会进行检测,检测代码为 isPrototypeCurrentlyInCreation(beanName) ,若是为 true,则会抛出异常。

  (5)检测parentBeanFactory代码上的逻辑能够看出,若是从缓存中没有取到,那么直接转到父类工厂上去加载了。由于代码中的判断逻辑是:if (parentBeanFactory != null && !containsBeanDefinition(beanName)),前半部分还好,parentBeanFactory 不能为空,后半部分 !containsBeanDefinition(beanName)意思若是当前的 beanDefinitionMap (XML配置文件)中没有 beanName 对应的配置,就只能到 parentBeanFactory 中去尝试下,再递归的调用 getBean()方法了。

  (6)GenericBeanDefinition转为RootBeanDefinition若是从缓存中获取不到,同时当前的 beanDefinitionMap 中存在对应 beanName 的配置,咱们就能够依据包含有XML配置文件信息的 beanDefinition 进行建立 bean 了。从XML配置文件中读取到的 bean 信息是利用 GenericBeanDefinition 存储的,可是后面Spring对全部 bean 的后续处理都是针对于 RootBeanDefinition 的,因此须要进行转换,转换的同时若是父类 bean 不为空,则会一并合并父类的属性。

  (7)寻找依赖由于 bean 的初始化过程当中极可能会用到某些属性,而某些属性极可能是动态配置的,而且配置的成功依赖于其余的 bean,那么此时应该先加载依赖的 bean。因此在流程中,Spring初始化一个 bean,会先初始化其依赖的全部的其余 bean。

  (8)依据scope建立beanSpring存在不一样的 scope,其中默认的是 singleton,可是还有其余的配置像 prototype、request 等。在这一步中,Spring会根据配置进行采起对应的初始化策略。

  (9)类型转换待 scope 建立完 bean 成功后,通常能够直接返回便可。但当传入 doGetBean 方法中的 requireType 参数不为空时,意味着咱们对最后返回的 bean 有着类型上的要求。Spring通常经过类型转换器将第八步建立完成的 bean 转换为 requireType 指定的类型。Spring自身提供了一些转换器,用户也能够本身扩辗转换器来知足需求。通过以上的九个步骤,bean 建立完成,这个时候返回的就是咱们须要的bean。其中第八步最为关键:针对不一样的 scope 进行 bean 的建立。

 

6、Bean的生命周期

  Spring的IoC容器功能很是强大,负责Spring的Bean的建立和管理等功能。而Spring 的bean是整个Spring应用中很重要的一部分,了解Spring Bean的生命周期对咱们了解整个spring框架会有很大的帮助。BeanFactory和ApplicationContext是Spring两种很重要的容器,前者提供了最基本的依赖注入的支持,然后者在继承前者的基础进行了功能的拓展,例如增长了事件传播,资源访问和国际化的消息访问等功能。下面介绍ApplicationContext和BeanFactory两种容器的Bean的生命周期。

  ApplicationContext Bean生命周期:

ApplicationContext Bean生命周期流程ApplicationContext容器中,Bean的生命周期流程如上图所示,流程大体以下:

  一、首先容器启动后,会对scope为singleton且非懒加载的bean进行实例化,

  二、按照Bean定义信息配置信息,注入全部的属性,

  三、若是Bean实现了BeanNameAware接口,会回调该接口的setBeanName()方法,传入该Bean的id,此时该Bean就得到了本身在配置文件中的id,

  四、若是Bean实现了BeanFactoryAware接口,会回调该接口的setBeanFactory()方法,传入该Bean的BeanFactory,这样该Bean就得到了本身所在的BeanFactory,

  五、若是Bean实现了ApplicationContextAware接口,会回调该接口的setApplicationContext()方法,传入该Bean的ApplicationContext,这样该Bean就得到了本身所在的ApplicationContext,

  六、若是有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessBeforeInitialzation()方法,

  七、若是Bean实现了InitializingBean接口,则会回调该接口的afterPropertiesSet()方法,

  八、若是Bean配置了init-method方法,则会执行init-method配置的方法,

  九、若是有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessAfterInitialization()方法,

  十、通过流程9以后,就能够正式使用该Bean了,对于scope为singleton的Bean,Spring的IoC容器中会缓存一份该bean的实例,而对于scope为prototype的Bean,每次被调用都会new一个新的对象,其生命周期就交给调用方管理了,再也不是Spring容器进行管理了,

  十一、容器关闭后,若是Bean实现了DisposableBean接口,则会回调该接口的destroy()方法,

  十二、若是Bean配置了destroy-method方法,则会执行destroy-method配置的方法,至此,整个Bean的生命周期结束。

 

  BeanFactory Bean生命周期流程图:

BeanFactory Bean生命周期流程:

  一、容器寻找Bean的定义信息,并将其实例化。

  二、使用依赖注入,Spring按照Bean定义信息配置Bean的全部属性。

  三、若是Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的id。

  四、若是实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。

  五、若是BeanPostProcessor和Bean关联,那么它们的postProcessBeforeInitialization()方法将被调用。(须要手动进行注册!)

  六、若是Bean实现了InitializingBean接口,则会回调该接口的afterPropertiesSet()方法。

  七、若是Bean指定了init-method方法,就会调用init-method方法。

  八、若是BeanPostProcessor和Bean关联,那么它的postProcessAfterInitialization()方法将被调用。(须要手动注册!)

  九、如今Bean已经能够使用了。scope为singleton的Bean缓存在Spring IOC容器中。scope为prototype的Bean生命周期交给客户端。

  十、销毁。若是Bean实现了DisposableBean接口,destory()方法将会被调用。若是配置了destory-method方法,就调用这个方法。

 

BeanFactoty容器中Bean的生命周期与ApplicationContext相比,有以下几点不一样:

  一、BeanFactory容器中,不会调用ApplicationContextAware接口的setApplicationContext()方法,

  二、BeanPostProcessor接口的postProcessBeforeInitialzation()方法和postProcessAfterInitialization()方法不会自动调用,必须本身经过代码手动注册,

  三、BeanFactory容器启动的时候,不会去实例化全部Bean,包括全部scope为singleton且非懒加载的Bean也是同样,而是在调用的时候去实例化。

 

Bean 实例建立时序图

 

Bean 对象关系创建流程图:

 

 

参考:

1. 《Spring源码深度解析》 郝佳 编著

2.  一天不进步就是退步  博客园

3. weixin_30439131 CSDN博客

4. 等一杯咖啡  CSDN博客

 

博众家之所长,集群英之荟萃。遴选各IT领域精品雄文!

欢迎关注“IT架构精选”

相关文章
相关标签/搜索