Ioc-BeanDefinition
内容大纲
本文主要讲述BeanDefinition的作用,以及BeanDefinition子接口或实现类的使用和介绍。
不会涉及BeanDefinitionReader(读取生成BeanDefinition)和BeanDefinitionRegistry(注册BeanDefinition)相关的东西,只关注BeanDefinition本身的东西。
BeanDefinition
前言
概述
BeanDefinition描述了一个bean实例,该实例具有属性值,构造函数参数值以及具体实现所提供的更多信息。
BeanDefinition主要是用来描述Bean,里面存放Bean元数据:比如Bean类名、scope、属性、构造函数参数列表、依赖的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
| public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { void setBeanClassName(@Nullable String beanClassName); String getBeanClassName(); void setScope(@Nullable String scope); String getScope();
void setLazyInit(boolean lazyInit); boolean isLazyInit();
void setDependsOn(@Nullable String... dependsOn); String[] getDependsOn();
void setPrimary(boolean primary); boolean isPrimary(); ConstructorArgumentValues getConstructorArgumentValues(); MutablePropertyValues getPropertyValues();
void setInitMethodName(@Nullable String initMethodName); String getInitMethodName();
void setDestroyMethodName(@Nullable String destroyMethodName); String getDestroyMethodName();
boolean isSingleton(); boolean isPrototype(); boolean isAbstract();
BeanDefinition getOriginatingBeanDefinition(); }
|
代码中BeanDefinition继承了AttributeAccessor
, BeanMetadataElement
两接口,让我们来看一下这两个接口。
1 2 3 4 5 6
| public interface BeanMetadataElement { default Object getSource() { return null; } }
|
AttributeAccessor
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public interface AttributeAccessor {
void setAttribute(String name, @Nullable Object value); Object getAttribute(String name); Object removeAttribute(String name); boolean hasAttribute(String name); String[] attributeNames(); }
|
AbstractBeanDefinition
概述
AbstractBeanDefinition是BeanDefinition最完整的实现,内部提供了大量的的属性字段来封装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
| public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable {
private volatile Object beanClass;
private String scope = SCOPE_DEFAULT;
private boolean abstractFlag = false;
private Boolean lazyInit; private int autowireMode = AUTOWIRE_NO; private int dependencyCheck = DEPENDENCY_CHECK_NONE; private String[] dependsOn; private boolean autowireCandidate = true; private boolean primary = false; private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>(); private Supplier<?> instanceSupplier; private boolean nonPublicAccessAllowed = true; private boolean lenientConstructorResolution = true; private String factoryBeanName; private String factoryMethodName; private ConstructorArgumentValues constructorArgumentValues; private MutablePropertyValues propertyValues; private MethodOverrides methodOverrides = new MethodOverrides(); private String initMethodName; private String destroyMethodName; private boolean enforceInitMethod = true; private boolean enforceDestroyMethod = true; private boolean synthetic = false; private int role = BeanDefinition.ROLE_APPLICATION; private String description; private Resource resource; @Override public Object clone() { return cloneBeanDefinition(); } public abstract AbstractBeanDefinition cloneBeanDefinition(); }
|
GenericBeanDefinition
概述
GenericBeanDefinition是一站式的用于标准bean定义。 像任何bean定义一样,它允许指定一个类以及可选的构造函数参数值和属性值。通过其parentName
属性灵活的指定父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
| public class GenericBeanDefinition extends AbstractBeanDefinition {
@Nullable private String parentName;
public GenericBeanDefinition() { super(); }
public GenericBeanDefinition(BeanDefinition original) { super(original); } public AbstractBeanDefinition cloneBeanDefinition() { return new GenericBeanDefinition(this); }
@Override public boolean equals(@Nullable Object other) { if (this == other) { return true; } if (!(other instanceof GenericBeanDefinition)) { return false; } GenericBeanDefinition that = (GenericBeanDefinition) other; return (ObjectUtils.nullSafeEquals(this.parentName, that.parentName) && super.equals(other)); } }
|
可以看出GenericBeanDefinition继承了AbstractBeanDefinition类,新增了一个parentName
属性。GenericBeanDefinition因为这个属性可以动态定义父依赖项,而不是将角色“硬编码”为根bean定义。
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Test public void testGenericBeanDefinition() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
GenericBeanDefinition parentBeanDefinition = new GenericBeanDefinition(); parentBeanDefinition.setBeanClass(IocParentBean.class); parentBeanDefinition.setBeanClassName(IocParentBean.class.getName()); parentBeanDefinition.setInitMethodName("init");
applicationContext.registerBeanDefinition("iocParentBean", parentBeanDefinition);
GenericBeanDefinition childBeanDefinition = new GenericBeanDefinition(); childBeanDefinition.setBeanClass(IocBean.class); childBeanDefinition.setParentName(parentBeanDefinition.getBeanClassName());
applicationContext.registerBeanDefinition("iocBean", childBeanDefinition);
System.out.println(applicationContext.getBeanDefinition("iocParentBean")); System.out.println(applicationContext.getBeanDefinition("iocBean")); }
|
示例结果
1 2 3
| Generic bean: class [io.better.spring.ioc.IocParentBean]; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=init; destroyMethodName=null Generic bean with parent 'io.better.spring.ioc.IocParentBean': class [io.better.spring.ioc.IocBean]; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
|
RootBeanDefinition
概述
一个RooBeanDefinition表示合并的BeanDefinition,该定义在运行时支持Spring BeanFactory中的特定bean。它可能是由多个相互继承的原始bean定义创建的,通常定义为GenericBeanDefinitions。RootBeanDefinition
本质上是运行时的 “统一” BeanDefinition 视图。
但是,从Spring 2.5开始,以编程方式注册bean定义的首选方法是GenericBeanDefinition类。
源代码
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
| public class RootBeanDefinition extends AbstractBeanDefinition {
private BeanDefinitionHolder decoratedDefinition; private AnnotatedElement qualifiedElement; volatile boolean stale; boolean allowCaching = true; boolean isFactoryMethodUnique = false; volatile ResolvableType targetType; volatile Class<?> resolvedTargetType; volatile Boolean isFactoryBean; volatile ResolvableType factoryMethodReturnType; volatile Method factoryMethodToIntrospect; final Object constructorArgumentLock = new Object(); Executable resolvedConstructorOrFactoryMethod; boolean constructorArgumentsResolved = false; Object[] resolvedConstructorArguments; Object[] preparedConstructorArguments;
final Object postProcessingLock = new Object();
boolean postProcessed = false; volatile Boolean beforeInstantiationResolved;
private Set<Member> externallyManagedConfigMembers; private Set<String> externallyManagedInitMethods; private Set<String> externallyManagedDestroyMethods; }
|
RootBeanDefiniiton保存了以下信息:
- 持有的BeanDefinitionHolder定义了id、别名与Bean的对应关系。
- AnnotatedElement获取Bean的注解信息。
- 具体的工厂方法(Class类型),包括工厂方法的返回类型,工厂方法的Method对象
- 缓存了构造函数、构造函数参数。
ChildBeanDefinition
从其父级继承设置的Bean的BeanDefinition。ChildBeanDefinition对父beanDefinition有固定的依赖性。ChildBeanDefinition将从父对象继承构造函数参数值,属性值和方法替代,并可以选择添加新值。如果指定了init方法,destroy方法和/或静态工厂方法,则它们将覆盖相应的父设置。其余设置将始终从子定义中获取:取决于,自动装配模式,依赖项检查,单例,懒加载。
从Spring 2.5开始,以编程方式注册Bean定义的首选方法是GenericBeanDefinition类。
AnnotatedBeanDefinition
AnnotatedBeanDefinition扩展了BeanDefinition,可向外暴露Bean的AnnotationMetadata
信息,无需加载Bean。
1 2 3 4 5 6 7
| public interface AnnotatedBeanDefinition extends BeanDefinition { AnnotationMetadata getMetadata(); MethodMetadata getFactoryMethodMetadata(); }
|
ScannedGenericBeanDefinition
概述
基于ASM ClassReader的GenericBeanDefinition类的扩展,支持通过AnnotatedBeanDefinition接口公开的注解元数据。此类不会尽早加载Bean类。而是从ASM ClassReader解析的“ .class”文件本身中检索所有相关的元数据。
它在功能上等效于AnnotatedGenericBeanDefinition.AnnotatedGenericBeanDefinition(AnnotationMetadata),但按类型区分已扫描的bean和已通过其他方式注册或检测的bean。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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()); }
@Override public final AnnotationMetadata getMetadata() { return this.metadata; } }
|
MetadataReader
:用于访问类元数据的简单入口,由ASM org.springframework.asm.ClassReader
读取。
示例代码
1 2 3
| @Component("iocBean1") @Order(1) public class IocBean {
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Test public void testScannedGenericBeanDefinition() throws Exception { SimpleMetadataReaderFactory simpleMetadataReaderFactory = new SimpleMetadataReaderFactory(); MetadataReader metadataReader = simpleMetadataReaderFactory.getMetadataReader("io.better.spring.ioc.IocBean");
ScannedGenericBeanDefinition beanDefinition = new ScannedGenericBeanDefinition(metadataReader);
AnnotationMetadata metadata = beanDefinition.getMetadata(); Set<String> annotationTypes = metadata.getAnnotationTypes();
System.out.println(annotationTypes); }
|
示例结果
1
| [org.springframework.stereotype.Component, org.springframework.core.annotation.Order]
|
AnnotatedGenericBeanDefinition
概述
AnnotatedGenericBeanDefinition
这个GenericBeanDefinition变体主要用于测试希望在AnnotatedBeanDefinition上运行的代码,例如Spring组件扫描支持中的策略实现(默认定义类是org.springframework.context.annotation.ScannedGenericBeanDefinition,它也实现了AnnotatedBeanDefinition接口) 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition { private final AnnotationMetadata metadata;
private MethodMetadata factoryMethodMetadata;
public AnnotatedGenericBeanDefinition(Class<?> beanClass) { setBeanClass(beanClass); this.metadata = AnnotationMetadata.introspect(beanClass); }
@Override public final AnnotationMetadata getMetadata() { return this.metadata; }
@Override @Nullable public final MethodMetadata getFactoryMethodMetadata() { return this.factoryMethodMetadata; } }
|
示例代码
1 2 3 4 5 6
| @Test public void testAnnotatedGenericBeanDefinition() { AnnotatedGenericBeanDefinition beanDefinition = new AnnotatedGenericBeanDefinition(IocBean.class); System.out.println(beanDefinition.getMetadata().getAnnotationTypes()); }
|
示例结果
1
| [org.springframework.stereotype.Component]
|
ConfigurationClassBeanDefinition
概述
该类是ConfigurationClassBeanDefinitionReader
中的私有静态内部类。
而ConfigurationClassBeanDefinitionReader
作用是将@Configuration
注解标识的类生成ConfigurationClass
实例,在通过ConfigurationClassBeanDefinition
将其转换成BeanDefinition并注册到BeanDefinitionRegistry
中。
而ConfigurationClassBeanDefinition
的作用就是将@Configuration
标识的类生成BeanDefinition(XML等其他配置源无效)。
源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| private static class ConfigurationClassBeanDefinition extends RootBeanDefinition implements AnnotatedBeanDefinition {
private final AnnotationMetadata annotationMetadata;
private final MethodMetadata factoryMethodMetadata;
public ConfigurationClassBeanDefinition(ConfigurationClass configClass, MethodMetadata beanMethodMetadata) { this.annotationMetadata = configClass.getMetadata(); this.factoryMethodMetadata = beanMethodMetadata; setLenientConstructorResolution(false); }
public AnnotationMetadata getMetadata() { return this.annotationMetadata; } }
|
在ConfigurationClassBeanDefinition构造函数中我们看到ConfigurationClass类,一个ConfigurationClass代表着一个用户定义的@Configuration类。
总结
- AbstractBeanDefinition:
- AbstractBeanDefinition是完善且具体的BeanDefinition类的基类,其中排除了GenericBeanDefinition,RootBeanDefinition和ChildBeanDefinition的常用属性。自动装配常数与AutowireCapableBeanFactory接口中定义的常数匹配。
- GenericBeanDefinition:
- GenericBeanDefinition是一站式的用于标准bean定义。 像任何bean定义一样,它允许指定一个类以及可选的构造函数参数值和属性值。
- AnnotatedBeanDefinition:
- 表示注解类型的BeanDefinition,有两个重要的属性,AnnotationMetadata,MethodMetadata分别表示BeanDefinition的注解元信息和方法元信息。
- RootBeanDefinition:
- 代表一个
Xml,Java Config
来的BeanDefinition
- ChildBeanDefinition:
- 可以让子Bean定义拥有从父Bean定义哪里继承配置的能力
- AnnotatedGenericBeanDefinition:
- 表示
@Configuration
注解注释的Bean
- ScannedGenericBeanDefinition:
- 表示
@Component、@Service、@Controller、@Repository
等注解注释的Bean