spring-beans/spring-bean-beanDefinitionHolder/README.md
BeanDefinition,以及 Spring 容器是如何管理和实例化 Bean 的。BeanDefinition的理解
BeanDefinition,它包含了哪些信息,例如 Bean 的类名、作用域、属性、初始化方法、销毁方法等。这是理解 BeanDefinitionHolder 的基础。BeanDefinition,以及如何从容器中获取 Bean 实例。BeanDefinitionHolder 是 Spring Framework 中的一个类,用于持有一个 BeanDefinition 对象以及与之相关联的名称。它通常用于内部 Spring 操作,用于管理和操作 BeanDefinition。
BeanDefinition 对象
BeanDefinitionHolder 主要用于持有一个 BeanDefinition 对象,它包含有关 Bean 的元数据信息,如类名、作用域、属性、初始化方法等。BeanDefinitionHolder 与一个 Bean 的名称相关联,以便可以轻松地标识和操作特定的 BeanDefinition。BeanDefinition
BeanDefinition 以及与之关联的名称,将它们组合在一起,形成一个单元,有助于更好地管理和处理 BeanDefinition。BeanDefinition 和名称,BeanDefinitionHolder 还可以包含其他元数据,如 BeanDefinition 的原始来源(通常是一个 Resource 对象)以及 BeanDefinition 的描述信息。BeanDefinition
BeanDefinitionHolder 可以与 BeanDefinitionRegistry 接口一起使用,用于在 Spring 容器中注册、修改和管理 BeanDefinition。BeanDefinitionHolder 通常在 Spring 内部用于处理 BeanDefinition 注册和操作,提供了访问 BeanDefinition、Bean 名称和别名的方法。
public class BeanDefinitionHolder implements BeanMetadataElement {
// 封装的 BeanDefinition 对象
private final BeanDefinition beanDefinition;
// Bean 的名称
private final String beanName;
// 别名数组
@Nullable
private final String[] aliases;
/**
* 创建一个新的 BeanDefinitionHolder。
* @param beanDefinition 要包装的 BeanDefinition
* @param beanName Bean 的名称,如在 Bean 定义中指定
*/
public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName) {
this(beanDefinition, beanName, null);
}
/**
* 创建一个新的 BeanDefinitionHolder。
* @param beanDefinition 要包装的 BeanDefinition
* @param beanName Bean 的名称,如在 Bean 定义中指定
* @param aliases Bean 的别名,如果没有别名则为 null
*/
public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName, @Nullable String[] aliases) {
Assert.notNull(beanDefinition, "BeanDefinition 必须不为 null");
Assert.notNull(beanName, "Bean 名称必须不为 null");
this.beanDefinition = beanDefinition;
this.beanName = beanName;
this.aliases = aliases;
}
/**
* 复制构造函数:创建一个新的 BeanDefinitionHolder,其内容与给定的 BeanDefinitionHolder 实例相同。
* 注意:封装的 BeanDefinition 引用保持原样;不会进行深层复制。
* @param beanDefinitionHolder 要复制的 BeanDefinitionHolder 实例
*/
public BeanDefinitionHolder(BeanDefinitionHolder beanDefinitionHolder) {
Assert.notNull(beanDefinitionHolder, "BeanDefinitionHolder 必须不为 null");
this.beanDefinition = beanDefinitionHolder.getBeanDefinition();
this.beanName = beanDefinitionHolder.getBeanName();
this.aliases = beanDefinitionHolder.getAliases();
}
/**
* 返回封装的 BeanDefinition。
*/
public BeanDefinition getBeanDefinition() {
return this.beanDefinition;
}
/**
* 返回 Bean 的主要名称,如在 Bean 定义中指定。
*/
public String getBeanName() {
return this.beanName;
}
/**
* 返回 Bean 的别名数组,如在 Bean 定义中直接指定。
* @return 别名数组,如果没有别名则为 null
*/
@Nullable
public String[] getAliases() {
return this.aliases;
}
/**
* 公开 Bean 定义的源对象。
* @see BeanDefinition#getSource()
*/
@Override
@Nullable
public Object getSource() {
return this.beanDefinition.getSource();
}
/**
* 确定给定的候选名称是否与存储在该 Bean 定义中的 Bean 名称或别名匹配。
*/
public boolean matchesName(@Nullable String candidateName) {
return (candidateName != null && (candidateName.equals(this.beanName) ||
candidateName.equals(BeanFactoryUtils.transformedBeanName(this.beanName)) ||
ObjectUtils.containsElement(this.aliases, candidateName)));
}
// ... [部分代码省略以简化]
}
BeanDefinitionHolder 不是一个接口,也不需要其他实现类。它是一个具体的类,用于包装 BeanDefinition 对象、Bean 名称和别名,以便更好地管理和操作 BeanDefinition。
使用 BeanDefinitionHolder 和 Spring IOC 容器,通过创建一个 BeanDefinition 对象定义了名为 "myBean" 的 Bean,然后给它指定了别名 "myBeanX" 和 "myBeanY",并最终将这个 BeanDefinition 注册到容器中。随后,使用容器的 getBean 方法来检索这些 Bean,验证它们的正确注册和别名的设置。
public class BeanDefinitionHolderDemo {
public static void main(String[] args) {
// 创建一个 DefaultListableBeanFactory,它是 BeanDefinitionRegistry 的一个实现
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 创建一个新的 BeanDefinition 对象
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(MyBean.class);
// Bean名称
String beanName = "myBean";
// 设置别名(aliases)
String[] aliases = {"myBeanX", "myBeanY"};
// 创建一个 BeanDefinitionHolder,将 BeanDefinition 与名称关联起来
BeanDefinitionHolder beanDefinitionHolder = new BeanDefinitionHolder(beanDefinition, beanName, aliases);
// 使用 BeanDefinitionReaderUtils 注册 BeanDefinitionHolder
BeanDefinitionReaderUtils.registerBeanDefinition(beanDefinitionHolder, beanFactory);
System.out.println("myBean = " + beanFactory.getBean("myBean"));
System.out.println("myBeanX = " + beanFactory.getBean("myBeanX"));
System.out.println("myBeanY = " + beanFactory.getBean("myBeanY"));
}
}
MyBean 的Java类,代表了一个简单的Java Bean。
public class MyBean {
}
运行结果发现,我们可以使多个名称都引用同一个Bean定义,最终获取相同的Bean实例。
myBean = com.xcs.spring.bean.MyBean@5bcea91b
myBeanX = com.xcs.spring.bean.MyBean@5bcea91b
myBeanY = com.xcs.spring.bean.MyBean@5bcea91b
BeanDefinitionReaderUtils
BeanDefinitionReaderUtils,用于帮助注册 BeanDefinition,它通常与 BeanDefinitionHolder 一起使用。BeanDefinitionReaderUtils.registerBeanDefinition 方法可用于将 BeanDefinitionHolder 注册到 BeanDefinitionRegistry 中。BeanDefinitionParser 和自定义解析器
BeanDefinition 可以通过自定义的 BeanDefinitionParser 或 NamespaceHandler 解析器来解析并注册到容器中。这些解析器通常使用 BeanDefinitionHolder 来包装 BeanDefinition,并通过解析器注册到容器中。ClassPathBeanDefinitionScanner 和 AnnotatedBeanDefinitionReader,用于扫描类路径或带有注解的类,并将它们注册为 BeanDefinition。这些扫描器通常使用 BeanDefinitionHolder 来包装扫描到的 BeanDefinition,并注册到容器中。@Import 注解以及相关的 ImportBeanDefinitionRegistrar 和 ImportSelector 接口用于导入其他配置类的 BeanDefinition。在这个过程中,BeanDefinitionHolder 可能用于包装被导入的 BeanDefinition,并将其注册到容器中。BeanDefinitionHolder?
BeanDefinitionHolder 通常在Spring内部用于处理BeanDefinition的注册和操作,但应用开发人员通常不需要直接与它交互(除非你是一个框架开发人员)。它可以在自定义BeanDefinition解析器、组件扫描、@Import导入等Spring配置的过程中被自动使用。BeanDefinitionHolder和BeanDefinition之间的关系是什么?
BeanDefinitionHolder 是一个包装器,它包含一个BeanDefinition对象以及相关的名称和别名。它用于将BeanDefinition与名称关联起来,以便更好地管理和操作BeanDefinition。BeanDefinition设置别名?
BeanDefinitionHolder构造函数中传递字符串数组来设置的。在注册BeanDefinitionHolder时,别名将与BeanDefinition一起注册,从而使不同的名称都引用同一个BeanDefinition。BeanDefinition注册到容器中,别名是固定的,不能在运行时更改。如果需要更改别名,通常需要重新注册BeanDefinition,使用不同的别名。BeanDefinitionHolder的matchesName方法来判断给定的候选名称是否与Bean的名称或别名匹配。这个方法会检查给定的名称是否与Bean名称或别名中的任何一个匹配。BeanDefinition?
BeanDefinition具有相同的名称,通常情况下,只有最后一个注册的BeanDefinition会生效。这可能会导致Bean覆盖的问题,因此在配置时要注意Bean名称的唯一性。