Spring BeanDefinition详解

BeanDefinition是定义Bean的配置元信息的接口,包含:

parentName父bean
classNamebean类名
scope作用域
isLazyInit是否懒加载
dependsOn依赖的bean
isAutowireCandidate是否可以注入到其他bean中,类型注入有效,名称注入无效
isPrimary是否主bean,同一个接口的多个实现,如果不指定名字,Spring会优先选择isPrimary为true的bean
factoryBeanName工场bean的名称
factoryMethodName工厂类的工厂方法名称
ConstructorArgumentValues构造器参数
PropertyValuesbean中的属性值
isSingleton是否单例
isPrototype是否多例
isAbstract如果这个bean被设置成"abstract",那么它将不能实例化
rolebean的角色APPLICATION – 指出该bean是应用程序的主要部分,通常对应用户定义的bean。SUPPORT – 应用支持性质的bean,在某些地方比较重要,但从整个应用的返回来看,还没那么重要。INFRASTRUCTURE – 基础设施bean,仅仅用于框架内部工作,跟终端用户无关。
Descriptionbean的描述
ResourceDescription资源描述文本,告知当前bean定义的来源,一般用于错误时显示上下文
OriginatingBeanDefinition返回来源bean定义(如果有的话)。通过该属性,可以获取被修饰的bean定义。需要注意的是该属性仅仅返回直接来源bean定义而不是返回最深处的来源bean定义。一个bean定义的originatingBeanDefinition属性隐含了一个来源bean定义链,通过迭代访问该链,可以最终找到最终来自用户的bean定义。

img

Spring Bean的总体创建过程如下,Spring会加载指定的java类将其变成BeanDefinition对象,然后根据BeanDefinition来创建Bean

img

继承体系

img

从类图中可以看出,BeanDefinition继承了AttributeAccessor和BeanMetadataElement两个接口;

AttributeAccessor
//将name定义的属性设置为提供的value值。如果value的值为null,则该属性为{@link #removeAttribute removed}。
//通常,用户应该注意通过使用完全限定的名称(可能使用类或包名称作为前缀)来防止与其他元数据属性重叠。
void setAttribute(String name, Object value);
//获取标识为name的属性的值。
Object getAttribute(String name);
//删除标识为name的属性,并返回属性值
Object removeAttribute(String name);
//如果名为name的属性是否存在,存在返回true,否则返回false。
boolean hasAttribute(String name);
//返回所有属性的名称。
String[] attributeNames();
BeanMetadataElement
//返回此元数据元素的配置源对象(可能为null)。
Object getSource();
AnnotatedBeanDefinition

AnnotatedBeanDefinitionBeanDefinition的子接口之一,扩展了两个方法,一般情况下通过注解方式得到的bean,其BeanDefinition类型都是该接口的实现类

public interface AnnotatedBeanDefinition extends BeanDefinition {
    // 获取当前bean的注解元数据
	AnnotationMetadata getMetadata();
    // 获取当前bean的工厂方法上的元数据
	@Nullable
	MethodMetadata getFactoryMethodMetadata();

}
AbstractBeanDefinition

AbstractBeanDefinition是最终全能BeanDefinition实现类的基类,也是这些类的公同属性和公共逻辑的实现

部分源码:

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
		implements BeanDefinition, Cloneable {
//	默认的SCOPE,默认是单例
	public static final String SCOPE_DEFAULT = "";

//	不进行自动装配
	public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;

//	根据Bean的名字进行自动装配,即autowired属性的值为byname
	public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;

//	根据Bean的类型进行自动装配,调用setter函数装配属性,即autowired属性的值为byType
	public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;

//	自动装配构造函数的形参,完成对应属性的自动装配,即autowired属性的值为byConstructor
	public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;

//通过Bean的class推断适当的自动装配策略(autowired=autodetect),如果Bean定义有有参构造函数,则通过自动装配构造函数形参,完成对应属性的自动装配(AUTOWIRE_CONSTRUCTOR),否则,使用setter函数(AUTOWIRE_BY_TYPE)
	@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;

	//若Bean未指定销毁方法,容器应该尝试推断Bean的销毁方法的名字
	public static final String INFER_METHOD = "(inferred)";

	//	Bean的class对象或是类的全限定名
	@Nullable
	private volatile Object beanClass;

	//bean的作用范围,对应bean属性scope是单例
	@Nullable
	private String scope = SCOPE_DEFAULT;

	//是否是抽象,对应bean属性abstract 	默认不为抽象类
	private boolean abstractFlag = false;
	
	//是否延迟加载,对应bean属性lazy-init
	@Nullable
	private Boolean lazyInit;
	//	默认不进行自动装配
	private int autowireMode = AUTOWIRE_NO;
	//	默认不进行依赖检查
	private int dependencyCheck = DEPENDENCY_CHECK_NONE;

	//用来表示一个bean的实例化依靠另一个bean先实例化
	//这里只会存放<bean/>标签的depends-on属性或是@DependsOn注解的值
	@Nullable
	private String[] dependsOn;

	//autowire-candidate属性设置为false,这样容器在查找自动装配对象时,
  	//将不考虑该bean,即它不会被考虑作为其他bean自动装配的候选者,
    //但是该bean本身还是可以使用自动装配来注入其他bean的
	private boolean autowireCandidate = true;
	
	//自动装配时出现多个bean候选者时,将作为首选者,对应bean属性primary
	private boolean primary = false;

	//用于记录Qualifier,对应子元素qualifier
	private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>();

	@Nullable
	private Supplier<?> instanceSupplier;

	//允许访问非公开的构造器和方法,程序设置
	private boolean nonPublicAccessAllowed = true;

	//是否以一种宽松的模式解析构造函数,默认为true
	private boolean lenientConstructorResolution = true;
	
	//对应bean属性factory-bean 工厂类名
	@Nullable
	private String factoryBeanName;
	
	//对应bean属性factory-method 工厂方法名
	@Nullable
	private String factoryMethodName;
	
	//记录构造函数注入属性,对应bean属性constructor-arg
	@Nullable
	private ConstructorArgumentValues constructorArgumentValues;
	
	//普通属性集合
	@Nullable
	private MutablePropertyValues propertyValues;
	
	//方法重写的持有者,记录lookup-method、replaced-method元素
	private MethodOverrides methodOverrides = new MethodOverrides();
	
	//初始化方法,对应bean属性init-method
	@Nullable
	private String initMethodName;
	
	//销毁方法,对应bean属性destroy-method
	@Nullable
	private String destroyMethodName;

	//是否执行init-method,程序设置
	private boolean enforceInitMethod = true;

	//是否执行destroy-method,程序设置
	private boolean enforceDestroyMethod = true;
	//是否是用户定义的而不是应用程序本身定义的,创建AOP时候为true,程序设置
	private boolean synthetic = false;
	//定义这个bean的应用,APPLICATION:用户,INFRASTRUCTURE:完全内部使用,与用户无关
	private int role = BeanDefinition.ROLE_APPLICATION;
	
	//bean的描述信息
	@Nullable
	private String description;
	//bean的资源
	@Nullable
	private Resource resource;

继承自AbstractBeanDefinition的全功能BeanDefinition实现类有 :

RootBeanDefinition、GenericBeanDefinition、ChildBeanDefinition

RootBeanDefinition– 不能设置parent bean定义

由此可见,RootBeanDefinition不能用于用于父子bean定义关系中的"子bean定义"

ChildBeanDefinition – 必须设置parent bean定义,而且必须是通过构造函数指定

ChildBeanDefinition很适合父子bean定义关系明确的情况下基于双亲bean定义和自身少量设置一些个性化属性从而进行子bean定义。

实际上,真正在创建子bean定义规定的bean对象时,Spring框架内部是将双亲bean定义和孩子bean定义合并形成一个最终使用的RootBeanDefinition,这里孩子bean定义中设置的属性会被优先使用,没有指定的都会继承使用双亲bean定义中的设置。

GenericBeanDefinition – 可以动态设置parent bean定义,也可以不设置parent bean定义

由此可见,GenericBeanDefinition既可以替代 RootBeanDefinition,也可以替代ChildBeanDefinition,所以GenericBeanDefinition更一般化(generic)

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值