0%

spring源码学习-BeanDefinition

前言:Spring BeanDefinition学习

简介

BeanDefinition是一个顶端接口,用于保存Bean的相关信息,类图如下:

image-20200102003610021

基于该接口,衍生出AbstractBeanDefinition、GenericBeanDefinition、RootBeanDefinition等

  • AbstractBeanDefinition:抽象类
  • AnnotatedGenericBeanDefinition:存储@Configuration注解注释的类
  • ChildBeanDefinition:存储子类bean,不可以单独存在,必须要依赖一个父BeanDetintion- ConfigurationClassBeanDefinition:以@Bean注解标记的Bean会被解析为ConfigurationClassBeanDefinition
  • GenericBeanDefinition:除了指定类、可选的构造函数参数值和属性参数外,还可以通过parenetName属性灵活设置父类的类全限定名
  • RootBeanDefinition:最常用的一个BeanDefinition,也可以作为其他BeanDefinition的父类。但是他不能作为其他BeanDefinition的子类
  • ScannedGenericBeanDefinition:存储@Component、@Service、@Controller等注解注释的类

AttributeAccessor

BeanDefinition继承的两个之一,声明了一系列关于属性的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
// 属性访问器
public interface AttributeAccessor {
// 设定指定的属性
void setAttribute(String name, Object value);
// 获取指定属性的值。
Object getAttribute(String name);
// 删除指定的属性并返回
Object removeAttribute(String name);
// 查询指定的属性是否存在,存在返回true,否则返回false。
boolean hasAttribute(String name);
// 返回所有属性的名称。
String[] attributeNames();
}

BeanMetadataElement

BeanDefinition继承的两个接口之一

1
2
3
4
5
6
// bean元数据元素
public interface BeanMetadataElement {
// 返回配置源对象,可以返回null:
Object getSource();

}

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
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
// 单例标识符(Spring容器仅创建一个对象)
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
// 原型标识符(Spring容器在用户每次获取该对象都创建一个新的对象)
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
// 用于描述Bean的角色,用户定义的Bean
int ROLE_APPLICATION = 0;
// 用于描述Bean的角色,Bean来自配置文件
int ROLE_SUPPORT = 1;
// 用于描述Bean的角色,Bean来自spring
int ROLE_INFRASTRUCTURE = 2;
// 设置父类类名
void setParentName(String parentName);
// 获取父类类名
String getParentName();
// 设置bean别名
void setBeanClassName(String beanClassName);
// 获取bean别名
String getBeanClassName();
// 设置bean作用域
void setScope(String scope);
// 获取bean作用域
String getScope();
// 设置延迟加载
void setLazyInit(boolean lazyInit);
// 是否延迟加载
boolean isLazyInit();
// 设置bean的依赖项
void setDependsOn(String... dependsOn);
// 获取bean依赖项
String[] getDependsOn();
// 设置是否可以注入bean
void setAutowireCandidate(boolean autowireCandidate);
// 是否可以注入bean
boolean isAutowireCandidate();
// 如果其他对象按照类型自动装配时发现有多个符合类型的多个实现bean,如果bean的primary属性为true,则以primary为true的优先,当然如果有多个primary为true,则抛出异常。
void setPrimary(boolean primary);
// 返回bean的primary属性
boolean isPrimary();
// 设置该bean的加载工厂
void setFactoryBeanName(String factoryBeanName);
// 获取bean的加载工厂
String getFactoryBeanName();
// 设置bean工厂的方法名
void setFactoryMethodName(String factoryMethodName);
// 获取bean工厂的方法名
String getFactoryMethodName();
// 获取bean的构造方法参数
ConstructorArgumentValues getConstructorArgumentValues();
// 获取properties文件中的键值对
MutablePropertyValues getPropertyValues();
// 是否单例
boolean isSingleton();
// 是否原型
boolean isPrototype();
// 是否抽象
boolean isAbstract();
// 获取标识符
int getRole();
// 获取描述信息
String getDescription();

String getResourceDescription();

BeanDefinition getOriginatingBeanDefinition();

}

总结,beanDefinition定义了定义了bean实例的基础方法,基本上通过BeanDefinition接口基本包含了操作一个bean的方法

有个问题,为什么不用Object储存bean对象,既然两者都可以存储bean对象,为啥是用BeanDefinition而不是Object呢?其实通过上面源码,除了存储bean对象,bean单例或原型、是否延迟加载bean对象、角色、别名、作用域,简单的通过Object对象是无法实现的,必须在此基础上有一个封装,这样才可以实现更多的自定义性质。

另外,在DefaultListableBeanFactory中,spring通过BeanDefinition把每个bean的信息,注册到容器的beanDefinitionMap中,后续对bean的操作就是从这个map取信息的。

最后BeanDefinition只是一个接口,定义了一系列的操作,描述Bean方法的相关属性交给了子类AbstractBeanDefinition,这个抽象类实现了BeanDefinition定义的一系列操作,RootBeanDefinition继承类AbstractBeanDefinition抽象类,在其基础上实现了更多功能

-------------本文结束感谢您的阅读-------------