Spring Framework:BeanDefinition 篇

本文详细介绍了Spring框架中的BeanDefinition,包括配置元数据的概念、BeanDefinition的定义类、实现以及配置元数据的载入方式。内容涵盖BeanDefinition如何表示配置信息、BeanDefinition接口及其属性、BeanDefinition的实现类,以及XML、注解和Java配置三种载入配置元数据的方法。
摘要由CSDN通过智能技术生成

IOC 容器:BeanDefinition 篇

在这里插入图片描述

参考文档:

  1. Spring 官方文档
  2. 《Spring 技术内幕:深入解析 Spring 架构与设计原理》

演示代码地址:

https://github.com/xuliangliang1995/grasswort-spring

涉及问题

  1. 什么是配置元数据(ConfigurationMetadata)?
  2. 什么是 BeanDefinition
  3. BeanDefinition 与配置元数据的关系?包含了哪些配置元数据?
  4. 配置元数据有哪些表现形式?以及相应的载入方式。

配置元信息(ConfigurationMetadata)

  1. 什么是配置元数据?

官方文档:

A Spring IoC container manages one or more beans. These beans are created with the configuration metadata that you supply to the container (for example, in the form of XML <bean/> definitions).

This configuration metadata represents how you, as an application developer, tell the Spring container to instantiate, configure, and assemble the objects in your application.

由此可知,配置元数据是指我们提供给 Spring 容器的一些配置信息,其中包含了 Bean 的定义信息,通过这些配置信息,我们可以告诉 Spring 容器如何去实例化、配置以及组装 Bean。

官方文档:

Within the container itself, these bean definitions are represented as BeanDefinition objects.

在容器内部,这些 Bean 的定义信息经过封装后表现为一个或多个 BeanDefinition 对象。spring 就是通过解析这些 BeanDefinition 实例来生成所定义的 Bean 实例。

Bean 的定义类(BeanDefinition)

  1. BeanDefinition 设计意图:

Java Doc 注释:

A BeanDefinition describes a bean instance, which has property values, constructor argument values, and further information supplied by concrete implementations.

This is just a minimal interface: The main intention is to allow a {@link BeanFactoryPostProcessor} to introspect and modify property values and other bean metadata.

BeanDefinitionspring 设计的用来描述一个 Bean 实例的接口。包含了许多关于 Bean 实例的信息。并且 spring 还设计了一个 BeanFactoryPostProcessor 容器后置处理器接口,可以在容器初始化阶段对 BeanDefinition 元数据或属性值进行修改。

  1. BeanDefinition 继承关系:

    在这里插入图片描述

BeanDefinitionspring 定义的一个用来描述 bean 实例的接口。它继承了 AttributeAccessorBeanMetadataElement 接口。

  • AttributeAccessor 要求 BeanDefinition 需要具备属性存储的能力。此处的属性并非指对象的 Field,而是近似于一个标签的作用,例如,ConfigurationClass 对应的 BeanDefinition 会在容器启动过程中标记一个 org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass 的属性,来标记为是配置类。
  • BeanMetadataElement 允许 BeanDefinition 配置一个类型为 Object 的配置源。
  1. BeanDefinition 接口中声明的方法:
/**
 * Set the name of the parent definition of this bean definition, if any.
 */
void setParentName(@Nullable String parentName);

/**
 * Return the name of the parent definition of this bean definition, if any.
 */
@Nullable
String getParentName();

说明 BeanDefinition 具备父子层级关系,子 BeanDefinition 可以复用父 BeanDefinition 中配置的元数据信息,从而减少不必要的重复配置。

/**
	 * Specify the bean class name of this bean definition.
	 * <p>The class name can be modified during bean factory post-processing,
	 * typically replacing the original class name with a parsed variant of it.
	 * @see #setParentName
	 * @see #setFactoryBeanName
	 * @see #setFactoryMethodName
	 */
	void setBeanClassName(@Nullable String beanClassName);

	@Nullable
	String getBeanClassName();

指定 BeanDefinition 对应的 Bean 实例化时所对应的 class 类。

/**
	 * Override the target scope of this bean, specifying a new scope name.
	 * @see #SCOPE_SINGLETON
	 * @see #SCOPE_PROTOTYPE
	 */
	void setScope(@Nullable String scope);

	@Nullable
	String getScope();

scope 为范围的意思,这里我们通常可以理解为作用域。不同作用域的 Bean 获取方式的内部实现策略可能会存在差异。 spring 提供了 singletonprototype 两种常用的作用域,分别对应设计模式中的单例模式和原型模式。

/**
	 * Set whether this bean should be lazily initialized.
	 * <p>If {@code false}, the bean will get instantiated on startup by bean
	 * factories that perform eager initialization of singletons.
	 */
	void setLazyInit(boolean lazyInit);

	boolean isLazyInit();

设置 Bean 是否延迟初始化,如果设置为 true ,在容器对单例对象进行预先初始化时,会跳过该 BeanDefinition 所对应 Bean 的实例化,而是在向容器第一次获取该 Bean 的时候才进行实例化。但如果该 Bean 是别的非延迟加载单例 Bean 的依赖对象时,则在容器对单例对象进行预先初始化是,也会被实例化。

/**
	 * Set the names of the beans that this bean depends on being initialized.
	 * The bean factory will guarantee that these beans get initialized first.
	 */
	void setDependsOn(@Nullable String... dependsOn);

	@Nullable
	String[] getDependsOn();

设置该 Bean 实例所依赖的其他 Beanspring 容器会先去初始化所依赖的其他 Bean

/**
	 * Set whether this bean is a candidate for getting autowired into some other bean.
	 * <p>Note that this flag is designed to only affect type-based autowiring.
	 * It does not affect explicit references by name, which will get resolved even
	 * if the specified bean is not marked as an autowire candidate. As a consequence,
	 * autowiring by name will nevertheless inject a bean if the name matches.
	 */
	void setAutowireCandidate(boolean autowireCandidate);

	boolean isAutowireCandidate();

设置该 Bean 是否为依赖注入候选者(把当前 Bean 注入到其他 Bean 中)。该属性仅影响基于类型的依赖注入。如果是通过 beanName 来进行依赖注入,则该属性不生效。

/**
	 * Set whether this bean is a primary autowire candidate.
	 * <p>If this value is {@code true} for exactly one bean among multiple
	 * matching candidates, it will serve as a tie-breaker.
	 */
	void setPrimary(boolean primary);

	boolean isPrimary();

设置该 Bean 是否为优先候选者,该属性同样是仅影响基于类型的依赖注入,当存在多个候选者时,会优先选用 primarytrue 的候选者(只能有一个)。否则系统将会因为无法选定候选者而抛出异常。

/**
	 * Specify the factory bean to use, if any.
	 * This the name of the bean to call the specified factory method on.
	 * @see #setFactoryMethodName
	 */
	void setFactoryBeanName(@Nullable String factoryBeanName);

	@Nullable
	String getFactoryBeanName();

	/**
	 * Specify a factory method, if any. This method will be invoked with
	 * constructor arguments, or with no arguments if none are specified.
	 * The method will be invoked on the specified factory bean, if any,
	 * or otherwise as a static method on the local bean class.
	 * @see #setFactoryBeanName
	 * @see #setBeanClassName
	 */
	void setFactoryMethodName(@Nullable String factoryMethodName);

	@Nullable
	String getFactoryMethodName();

setFactoryBeanNamesetFactoryMethodName 对应设计模式中的工厂模式。 setFactoryBeanName(String factoryBeanName) 指定生产 Bean 的工厂实例,setFactoryMethodName 指定对应的工厂方法名称。

/**
	 * Return the constructor argument values for this bean.
	 * <p>The returned instance can be modified during bean factory post-processing.
	 * @return the ConstructorArgumentValues object (never {@code null})
	 */
	ConstructorArgumentValues getConstructorArgumentValues();

	default boolean hasConstructorArgumentValues() {
   
		return !getConstructorArgumentValues().isEmpty();
	}

获取构造参数值,对应类实例化时调用构造函数的参数值。如果是通过工厂方法来生成实例的话,则对应工厂方法的参数值。

/**
	 * Return the property values to be applied to a new instance of the bean.
	 * <p>The returned instance can be modified during bean factory post-processing.
	 * @return the MutablePropertyValues object (never {@code null})
	 */
	MutablePropertyValues getPropertyValues();

	default boolean hasPropertyValues() {
   
		return !getPropertyValues().isEmpty();
	}

获取所描述Bean 实例的属性值,Mutable 为可修改的意思,获取 MutablePropertyValues 对象后可以对里面的 PropertyValue 进行编辑修改。

	void setInitMethodName(@Nullable String initMethodName);

	@Nullable
	String getInitMethodName();

	void setDestroyMethodName(@Nullable String destroyMethodName);

	@Nullable
	String getDestroyMethodName();

以上方法分别为设置 Bean 实例的初始化方法,和销毁方法。

	void setRole(int role);

	int getRole();

设置 Bean 的角色,该方法没有什么功能上的意义。仅用来对 Bean 做一个功能上的标识。

	void setDescription(@Nullable String description);

	@Nullable
	String getDescription();

设置类的描述信息。

	/**
	 * Return a resolvable type for this bean definition,
	 * based on the bean class or other specific metadata.
	 * <p>This is typically fully resolved on a runtime-merged bean definition
	 * but not necessarily on a configuration-time definition instance.
	 * @return the resolvable type (potentially {@link ResolvableType#NONE})
	 * @since 5.2
	 * @see ConfigurableBeanFactory#getMergedBeanDefinition
	 */
	ResolvableType getResolvableType();

获取该 BeanDefinition 所描述 BeanResolvableTypeResolvableTypespring 设计的一个支持获取泛型信息的接口,方便泛型操作。

  boolean isSingleton();

	boolean isPrototype();

	/**
	 * Return whether this bean is "abstract", that is, not meant to be instantiated.
	 */
	boolean 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值