SpringIOC-BeanDefinition介绍
什么是BeanDefinition 在Java中,一切皆对象。在JDK中使用java.lang.Class
来描述类
这个对象。
用过spring的人都知道,我们将对象注入到spring容器中,交给spring来帮我们管理。这种对象我们称之为bean对象。但是这些bean对象在spring容器中,到底是以什么形式存在,具有哪些属性、行为呢?今天我们进入到spring源码来一探究竟。
在Spring中,存在bean
这样一个概念,那Spring又是怎么抽象bean
这个概念,用什么类来描述bean
这个对象呢?Spring使用BeanDefinition
来描述bean
。
BeanDefinition 的作用 在前面分析Spring IoC容器的时候,贯穿全文的一个概念:Bean定义信息。它是Spring容器的一个核心概念,那么本文就深入分析一下BeanDefinition
这个接口(类)。
Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构 。
不管是是通过xml配置文件的<bean>标签,还是通过注解配置的@Bean,还是通扫描的@Component,它最终都会被解析成一个Bean定义信息(对象),最后我们的Bean工厂就会根据这份Bean的定义信息,对bean进行实例化、初始化等等操作
从上可知BeanDefinition
这个接口对Spring IoC容器的重要之处,所以了解好了它(以及子类),能让我们更大视野的来看Spring管理Bean的一个过程,也能透过现象看本质。
BeanFactory和BeanDefinition Spring IoC容器比作一间餐馆,当你来到餐馆,通常会直接招呼服务员:点菜!至于菜的原料是什么?如何用原料把菜做出来?可能你根本就不关心。 IoC容器也是一样,你只需要告诉它需要某个bean,它就把对应的实例(instance)扔给你,至于这个bean是否依赖其他组件,怎样完成它的初始化,根本就不需要你关心。
那么问题来了,作为餐馆,想要做出菜肴,得知道菜的原料和菜谱。同样地,IoC容器想要管理各个业务对象以及它们之间的依赖关系,需要通过某种途径来记录和管理这些信息。 BeanDefinition对象就承担了这个责任
容器中的每一个bean都会有一个对应的BeanDefinition实例,该实例负责保存bean对象的 所有 必要信息,包括bean对象的class类型、是否是抽象类、构造方法和参数、其它属性等等(所以BeanDefinition就好比做菜的原料)
需要说明的一点是:加入你是自己直接通过 SingletonBeanRegistry#registerSingleton向容器手动注入Bean的,那么就不会存在这份Bean定义信息的,这点需要注意。 Spring内部有不少这样的例子(因为这种Bean非常简单,根本不需要定义信息): beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); beanFactory.registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator); bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, servletContext); bf.registerSingleton(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME, Collections.unmodifiableMap(attributeMap));
现在可以开始做菜了吗?其实还不行,因为还没有菜谱(不知道做什么菜,怎么做~) BeanDefinitionRegistry和 BeanFactory就是这份菜谱,BeanDefinitionRegistry抽象出bean的注册逻辑,而BeanFactory则抽象出了bean的管理逻辑 各个BeanFactory的实现类就具体承担了bean的注册以及管理工作
DefaultListableBeanFactory作为一个比较通用的BeanFactory实现,它同时也实现了BeanDefinitionRegistry接口,因此它就承担了Bean的注册管理工作
最后我们总结一下比喻关系:
Spring IoC容器:餐馆(服务员)
BeanDefinitionRegistry和 BeanFactory:菜谱
BeanDefinitionRegistry:抽象出来的,向菜谱里注册菜(的管理器)
BeanFactory:抽象出来的,管理这些菜谱(的管理器)
BeanDefinition:原料(做菜所需要的原料)
DefaultListableBeanFactory:具体实施者(具体注册菜谱、做菜的实施者) 依赖注入的使用者:客户(进店吃饭的人)
BeanDefinition 的属性
属性
行为
解释
parentName
String getParentName(); void setParentName(@Nullable String parentName);
bean定义对象的父类定义对象名称
beanClassName
String getBeanClassName(); void setBeanClassName(@Nullable String beanClassName);
bean对象的实际class类
scope
String getScope(); void setScope(@Nullable String scope);
bean对象是否为单例<singleton或者prototype>
lazyInit
boolean isLazyInit(); void setLazyInit(boolean lazyInit);
是否懒加载
dependsOn
String[] getDependsOn(); void setDependsOn(@Nullable String… dependsOn);
设置依赖的bean对象,被依赖的bean对象总是会比当前bean对象先创建
autowireCandidate
boolean isAutowireCandidate(); void setAutowireCandidate(boolean autowireCandidate);
设置是否可以自动注入。只对@Autowired注解有效,配置文件中可以通过property显示注入
primary
boolean isPrimary(); void setPrimary(boolean primary);
配置bean为主要候选bean。当同一个接口的多个实现类或者一个类多次注入到spring容器时,通过该属性来配置某个bean为主候选bean,通过类型来注入时,默认为使用主候选bean注入
factoryBeanName
String getFactoryBeanName(); void setFactoryBeanName(@Nullable String factoryBeanName);
设置创建bean的工厂名称
factoryMethodName
String getFactoryMethodName(); void setFactoryMethodName(@Nullable String factoryMethodName);
设置创建bean的工厂中,创建bean的具体方法
initMethodName
String getInitMethodName(); void setInitMethodName(@Nullable String initMethodName);
设置创建bean时,默认初始化的方法
destroyMethodName
String getDestroyMethodName(); void setDestroyMethodName(@Nullable String destroyMethodName);
设置销毁bean时调用的方法名称。注意需要调用context的close()方法才会调用
role
int getRole(); void setRole(int role);
设置bean的分类
description
String getDescription(); void setDescription(@Nullable String description);
对bean对象的描述
BeanDefinition 的继承关系
BeanDefinition的实现类 ChildBeanDefinition
ChildBeanDefinition是一种bean definition,它可以继承它父类的设置,即ChildBeanDefinition对RootBeanDefinition有一定的依赖关系。
ChildBeanDefinition从父类继承构造参数值,属性值并可以重写父类的方法,同时也可以增加新的属性或者方法。(类同于java类的继承关系)。若指定初始化方法,销毁方法或者静态工厂方法,ChildBeanDefinition将重写相应父类的设置。depends on,autowire mode,dependency check,sigleton,lazy init 一般由子类自行设定。
GenericBeanDefinition 注意:从spring 2.5 开始,提供了一个更好的注册bean definition类GenericBeanDefinition,它支持动态定义父依赖,方法是GenericBeanDefinition.setParentName(java.lang.String),GenericBeanDefinition可以有效的替代ChildBeanDefinition的绝大分部使用场合。
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 一个RootBeanDefinition定义表明它是一个可合并的bean definition:即在spring beanFactory运行期间,可以返回一个特定的bean。RootBeanDefinition可以作为一个重要的通用的bean definition 视图。
RootBeanDefinition用来在配置阶段进行注册bean definition。然后,从spring 2.5后,编写注册bean definition有了更好的的方法:GenericBeanDefinition。GenericBeanDefinition支持动态定义父类依赖,而非硬编码作为root bean definition。
源码分析
因为它继承了AttributeAccessor,和BeanMetadataElement
,所以我们先有必要来了解下这两个接口:
AttributeAccessor
定义了对对象元数据访问的抽象接口
1 2 3 4 5 6 7 8 9 10 11 12 public interface AttributeAccessor { void setAttribute (String name, @Nullable Object value) ; @Nullable Object getAttribute (String name) ; @Nullable Object removeAttribute (String name) ; boolean hasAttribute (String name) ; String[] attributeNames(); }
AttributeAccessorSupport
是唯一抽象实现,内部基于LinkedHashMap
实现了所有的接口,供其他子类继承使用 主要针对属性CRUD操作
具有访问source(配置源)的能力,这个方法在@Configuration
中使用较多,因为它会被代理
1 2 3 4 5 6 7 8 9 10 11 public interface BeanMetadataElement { @Nullable Object getSource () ; }
BeanDefinition
定义了Bean的各种信息
一个BeanDefinition描述了一个bean的实例,包括属性值,构造方法参数值和继承自它的类的更多信息。
BeanDefinition
仅仅是一个最简单的接口,主要功能是允许BeanFactoryPostProcessor
例如PropertyPlaceHolderConfigure
能够检索并修改属性值和别的bean的元数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 public interface BeanDefinition extends AttributeAccessor , BeanMetadataElement { String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE; int ROLE_APPLICATION = 0 ; int ROLE_SUPPORT = 1 ; int ROLE_INFRASTRUCTURE = 2 ; void setParentName (@Nullable String parentName) ; @Nullable String getParentName () ; void setBeanClassName (@Nullable String beanClassName) ; @Nullable String getBeanClassName () ; void setScope (@Nullable String scope) ; @Nullable String getScope () ; void setLazyInit (boolean lazyInit) ; boolean isLazyInit () ; void setDependsOn (@Nullable String... dependsOn) ; @Nullable String[] getDependsOn(); void setAutowireCandidate (boolean autowireCandidate) ; boolean isAutowireCandidate () ; void setPrimary (boolean primary) ; boolean isPrimary () ; void setFactoryBeanName (@Nullable String factoryBeanName) ; @Nullable String getFactoryBeanName () ; void setFactoryMethodName (@Nullable String factoryMethodName) ; @Nullable String getFactoryMethodName () ; ConstructorArgumentValues getConstructorArgumentValues () ; default boolean hasConstructorArgumentValues () { return !getConstructorArgumentValues().isEmpty(); } MutablePropertyValues getPropertyValues () ; default boolean hasPropertyValues () { return !getPropertyValues().isEmpty(); } boolean isSingleton () ; boolean isPrototype () ; boolean isAbstract () ; int getRole () ; @Nullable String getDescription () ; @Nullable String getResourceDescription () ; @Nullable BeanDefinition getOriginatingBeanDefinition () ; }
抽象实现、实现类们。上面已经画出了一些类的结构图,下面一个个来看
AnnotatedBeanDefinition
AnnotationMetadata定义了访问特定类的注解的抽象接口,
它不需要加载该类即可访问
1 2 3 4 5 6 7 8 9 public interface AnnotatedBeanDefinition extends BeanDefinition { AnnotationMetadata getMetadata () ; @Nullable MethodMetadata getFactoryMethodMetadata () ; }
该注解Bean定义旗下三大实现类 :ScannedGenericBeanDefinition,ConfigurationClassBeanDefinition,AnnotatedGenericBeanDefinition
AbstractBeanDefinition
AbstractBeanDefinition
实现了BeanDefinition
定义的一系列操作,定义了描述Bean画像的一系列属性,在AbstractBeanDefinition
的基础上,Spring
衍生出了一系列具有特殊用途的BeanDefinition
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition , Cloneable { public static final String SCOPE_DEFAULT = "" ; public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO; public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME; public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE; public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR; @Deprecated public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT; public static final int DEPENDENCY_CHECK_NONE = 0 ; public static final int DEPENDENCY_CHECK_OBJECTS = 1 ; public static final int DEPENDENCY_CHECK_SIMPLE = 2 ; public static final int DEPENDENCY_CHECK_ALL = 3 ; public static final String INFER_METHOD = "(inferred)" ; @Nullable private volatile Object beanClass; @Nullable private String scope = SCOPE_DEFAULT; private boolean abstractFlag = false ; private boolean lazyInit = false ; private int autowireMode = AUTOWIRE_NO; private int dependencyCheck = DEPENDENCY_CHECK_NONE; @Nullable private String[] dependsOn; private boolean autowireCandidate = true ; private boolean primary = false ; private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap <>(0 ); @Nullable private Supplier<?> instanceSupplier; private boolean nonPublicAccessAllowed = true ; private boolean lenientConstructorResolution = true ; @Nullable private String factoryBeanName; @Nullable private String factoryMethodName; @Nullable private ConstructorArgumentValues constructorArgumentValues; @Nullable private MutablePropertyValues propertyValues; @Nullable private MethodOverrides methodOverrides; @Nullable private String initMethodName; @Nullable private String destroyMethodName; private boolean enforceInitMethod = true ; private boolean enforceDestroyMethod = true ; private boolean synthetic = false ; private int role = BeanDefinition.ROLE_APPLICATION; @Nullable private String description; @Nullable private Resource resource; public void setOriginatingBeanDefinition (BeanDefinition originatingBd) { this .resource = new BeanDefinitionResource (originatingBd); } public BeanDefinition getOriginatingBeanDefinition () { return (this .resource instanceof BeanDefinitionResource ? ((BeanDefinitionResource) this .resource).getBeanDefinition() : null ); } @Override public Object clone () { return cloneBeanDefinition(); } public abstract AbstractBeanDefinition cloneBeanDefinition () ; }
AbstractBeanDefinition定义了一系列描述Bean画像的属性,通过这个类,可以窥见Bean的某些默认设置(例如默认为单例等)。
从上图可以看出,接下俩需要看具体衍生出来的实现类了,先看RootBeanDefinition
、ChildBeanDefinition
、GenericBeanDefinition
。他们都是AbstractBeanDefinition
的直接实现类
GenericBeanDefinition
标准bean definition,通用的
除了具有指定类、可选的构造参数值和属性参数这些其它bean definition
一样的特性外,它还具有通过parenetName
属性来灵活(动态)
设置parent bean definition,而非硬编码作为root bean definition
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public static void main (String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext (RootConfig.class); GenericBeanDefinition parentBeanDef = new GenericBeanDefinition (); parentBeanDef.setBeanClass(Parent.class); parentBeanDef.setBeanClassName(Parent.class.getName()); parentBeanDef.setScope(BeanDefinition.SCOPE_SINGLETON); GenericBeanDefinition childBeanDef = new GenericBeanDefinition (); childBeanDef.setParentName(parentBeanDef.getBeanClassName()); childBeanDef.setBeanClass(Child.class); applicationContext.registerBeanDefinition("parent" , parentBeanDef); applicationContext.registerBeanDefinition("child" , childBeanDef); System.out.println(applicationContext.getBeanDefinition("parent" )); System.out.println(applicationContext.getBeanDefinition("child" )); }
GenericBeanDefinition
源码实现非常的的简单,只增加了一个parentName
的属性值,其余的实现都在父类AbstractBeanDefinition
里
备注:若你是xml配置,最初被加载进来都是一个GenericBeanDefinition
,之后再逐渐解析的。
ChildBeanDefinition
子Bean定义信息,依赖于父类RootBeanDefinition
ChildBeanDefinition
是一种bean definition,它可以继承它父类的设置,即ChildBeanDefinition
对RootBeanDefinition
有一定的依赖关系 。
从spring 2.5 开始,提供了一个更好的注册bean definition类GenericBeanDefinition
,所以以后推荐使用它。
RootBeanDefinition
一个RootBeanDefinition定义表明它是一个可合并的bean definition:即在spring beanFactory运行期间,可以返回一个特定的bean。但在Spring2.5以后,我们绝大多数情况还是可以使用GenericBeanDefinition来做。
我们非常熟悉的final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);这句代码,就是去合并parent的属性进来,这样体现了继承的强大。属性也才完整。
在 配置文件中可以定义父和子,父用RootBeanDefinition表示, 而子用ChildBeanDefiniton表示,而没有父的就使用 RootBeanDefinition表示。下面看看源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 public class RootBeanDefinition extends AbstractBeanDefinition { @Nullable private BeanDefinitionHolder decoratedDefinition; @Nullable private AnnotatedElement qualifiedElement; boolean allowCaching = true ; boolean isFactoryMethodUnique = false ; @Nullable volatile ResolvableType targetType; @Nullable volatile Class<?> resolvedTargetType; @Nullable volatile ResolvableType factoryMethodReturnType; final Object constructorArgumentLock = new Object (); @Nullable Executable resolvedConstructorOrFactoryMethod; boolean constructorArgumentsResolved = false ; @Nullable Object[] resolvedConstructorArguments; @Nullable Object[] preparedConstructorArguments; final Object postProcessingLock = new Object (); boolean postProcessed = false ; @Nullable volatile Boolean beforeInstantiationResolved; @Nullable private Set<Member> externallyManagedConfigMembers; @Nullable private Set<String> externallyManagedInitMethods; @Nullable private Set<String> externallyManagedDestroyMethods; @Override public String getParentName () { return null ; } @Override public void setParentName (@Nullable String parentName) { if (parentName != null ) { throw new IllegalArgumentException ("Root bean cannot be changed into a child bean with parent reference" ); } } @Nullable public Class<?> getTargetType() { if (this .resolvedTargetType != null ) { return this .resolvedTargetType; } ResolvableType targetType = this .targetType; return (targetType != null ? targetType.resolve() : null ); } @Override public RootBeanDefinition cloneBeanDefinition () { return new RootBeanDefinition (this ); } }
可以看到许多与反射相关的对象,这说明spring底层采用的是反射机制
总结一下,RootBeanDefiniiton保存了以下信息:
定义了id、别名与Bean的对应关系(BeanDefinitionHolder)
Bean的注解(AnnotatedElement)
具体的工厂方法(Class类型),包括工厂方法的返回类型,工厂方法的Method对象
构造函数、构造函数形参类型
Bean的class对象
可以看到,RootBeanDefinition与AbstractBeanDefinition是互补关系,RootBeanDefinition在AbstractBeanDefinition的基础上定义了更多属性,初始化Bean需要的信息基本完善
AnnotatedBeanDefinition的相关子类 ScannedGenericBeanDefinition
存储@Component、@Service、@Controller等注解注释的类
它的源码很简单,就是多了一个属性:private final AnnotationMetadata metadata
用来存储扫描进来的Bean的一些注解信息。
1 2 3 4 5 6 7 8 9 10 11 public class ScannedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition { private final AnnotationMetadata metadata; ... public ScannedGenericBeanDefinition (MetadataReader metadataReader) { Assert.notNull(metadataReader, "MetadataReader must not be null" ); this .metadata = metadataReader.getAnnotationMetadata(); setBeanClassName(this .metadata.getClassName()); } }
AnnotatedGenericBeanDefinition
在基于注解驱动的Spring应用着,它使用得非常的多。因为获取注解信息非常的方便~
只能用于已经被注册或被扫描到的类(否则你手动new一个,它就不在容器里了,那就脱离管理了)
使用案例 1 2 3 4 5 6 7 8 public static void main (String[] args) { AnnotatedBeanDefinition beanDefinition = new AnnotatedGenericBeanDefinition (RootConfig.class); Set<String> annotationTypes = beanDefinition.getMetadata().getAnnotationTypes(); System.out.println(annotationTypes); System.out.println(beanDefinition.isSingleton()); System.out.println(beanDefinition.getBeanClassName()); }
源码参考 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition { private final AnnotationMetadata metadata; @Nullable private MethodMetadata factoryMethodMetadata; public AnnotatedGenericBeanDefinition (Class<?> beanClass) { setBeanClass(beanClass); this .metadata = new StandardAnnotationMetadata (beanClass, true ); } public AnnotatedGenericBeanDefinition (AnnotationMetadata metadata) { Assert.notNull(metadata, "AnnotationMetadata must not be null" ); if (metadata instanceof StandardAnnotationMetadata) { setBeanClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass()); } else { setBeanClassName(metadata.getClassName()); } this .metadata = metadata; } public AnnotatedGenericBeanDefinition (AnnotationMetadata metadata, MethodMetadata factoryMethodMetadata) { this (metadata); Assert.notNull(factoryMethodMetadata, "MethodMetadata must not be null" ); setFactoryMethodName(factoryMethodMetadata.getMethodName()); this .factoryMethodMetadata = factoryMethodMetadata; } @Override public final AnnotationMetadata getMetadata () { return this .metadata; } @Override @Nullable public final MethodMetadata getFactoryMethodMetadata () { return this .factoryMethodMetadata; } }
ConfigurationClassBeanDefinition
首先需要注意的是,它是ConfigurationClassBeanDefinitionReader
的一个私有的静态内部类:这个类负责将@Bean注解的方法转换为对应的ConfigurationClassBeanDefinition类(非常的重要)
1 2 3 4 private static class ConfigurationClassBeanDefinition extends RootBeanDefinition implements AnnotatedBeanDefinition { ... 源码和之前的差得不是太多,此处就不解释了 }
默认的设置
如果@Bean注解没有指定bean的名字,默认会用方法的名字命名bean
@Configuration注解的类会成为一个工厂类,而所有的@Bean注解的方法会成为工厂方法,通过工厂方法实例化Bean,而不是直接通过构造函数初始化 (所以我们方法体里面可以很方便的书写逻辑。。。)
BeanDefinition的使用
Spring
初始化时,会用GenericBeanDefinition
或是ConfigurationClassBeanDefinition
(用@Bean注解注释的类 )存储用户自定义的Bean,在初始化Bean时,又会将其转换为RootBeanDefinition
。
BeanDefinitionBuilder
快速创建一个Bean定义
使用它的好处是,可以进行方法的连缀。 没有特殊指明,创建的都是GenericBeanDefinition
,源码非常的简单,下面只用个Deme看看即可
1 2 3 4 5 6 7 8 9 10 11 12 13 public class BeanDefinitionBuilder { public static BeanDefinitionBuilder genericBeanDefinition () { return new BeanDefinitionBuilder (new GenericBeanDefinition ()); } .... public static BeanDefinitionBuilder rootBeanDefinition (String beanClassName) { return rootBeanDefinition(beanClassName, null ); } public static BeanDefinitionBuilder childBeanDefinition (String parentName) { return new BeanDefinitionBuilder (new ChildBeanDefinition (parentName)); } }
示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public static void main (String[] args) { AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Child.class) .setRole(BeanDefinition.ROLE_APPLICATION) .setScope(BeanDefinition.SCOPE_SINGLETON) .addPropertyValue("name" , "fsx" ) .setLazyInit(false ) .applyCustomizers((bdf) -> { AbstractBeanDefinition abdf = (AbstractBeanDefinition) bdf; abdf.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_NO); }).getRawBeanDefinition(); System.out.println(beanDefinition); }
BeanDefinitionReader
该接口的作用就是加载 Bean
在 Spring 中,Bean 一般来说都在配置文件中定义。而在配置的路径由在 web.xml 中定义(还有全注解的方 式)。所以加载 Bean 的步骤大致就是:
加载资源,通过配置文件的路径(Location)加载配置文件(Resource)
解析资源,通过解析配置文件的内容得到 Bean。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public interface BeanDefinitionReader { BeanDefinitionRegistry getRegistry () ; @Nullable ResourceLoader getResourceLoader () ; @Nullable ClassLoader getBeanClassLoader () ; BeanNameGenerator getBeanNameGenerator () ; int loadBeanDefinitions (Resource resource) throws BeanDefinitionStoreException; int loadBeanDefinitions (Resource... resources) throws BeanDefinitionStoreException; int loadBeanDefinitions (String location) throws BeanDefinitionStoreException; int loadBeanDefinitions (String... locations) throws BeanDefinitionStoreException; }
它的继承结构非常简单,一个抽象实现+3个具体实现
AbstractBeanDefinitionReader
它实现了一些基本的方法,但是核心方法loadBeanDefinitions
肯定是交给子类实现了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable , BeanDefinitionReader { private final BeanDefinitionRegistry registry; @Nullable private ResourceLoader resourceLoader; @Nullable private ClassLoader beanClassLoader; private Environment environment; private BeanNameGenerator beanNameGenerator = new DefaultBeanNameGenerator (); protected AbstractBeanDefinitionReader (BeanDefinitionRegistry registry) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null" ); this .registry = registry; if (this .registry instanceof ResourceLoader) { this .resourceLoader = (ResourceLoader) this .registry; } else { this .resourceLoader = new PathMatchingResourcePatternResolver (); } if (this .registry instanceof EnvironmentCapable) { this .environment = ((EnvironmentCapable) this .registry).getEnvironment(); } else { this .environment = new StandardEnvironment (); } } public void setEnvironment (Environment environment) { Assert.notNull(environment, "Environment must not be null" ); this .environment = environment; } public void setBeanNameGenerator (@Nullable BeanNameGenerator beanNameGenerator) { this .beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new DefaultBeanNameGenerator ()); } ... }