Spring中的BeanDefinitionRegistry接口
BeanDefinitionRegistry描述#
Javadoc#
BeanDefinitionRegistry包含beanDefinition的注册表的接口(例如RootBeanDefinition和ChildBeanDefinition实例);通常由内部与 AbstractBeanDefinition 层次结构一起工作的BeanFactorty实现;这是Spring的bean工厂包中唯一封装了beanDefinition注册的接口标;准BeanFactory接口仅涵盖对完全配置的工厂实例的访问;BeanDefinition的解析器可以使用此接口的实现类来进行逻辑处理,Spring中的已知实现为DefaultListableBeanFactory和GenericApplicationContext;
通俗地说,BeanDefinitionRegistry是维护BeanDefinition的注册表接口,它内部存放了Spring容器中beanDefiniton的信息,同时BeanDefinitionRegistry是用于支撑其他组件和动态注册Bean的组件,BeanDefinitionRegistry的主要实现是DefaultListableBeanFactory;
BeanDefinitionRegistry与BeanDefinition的关系#
-
BeanDefinitionRegistry存放了所有的BeanDefinition的设置信息#
BeanDefinitionRegistry存放了所有的BeanDefinition的设置信息,存储的结构为Map,key为beanName,value为BeanDefinition的实例;
org.springframework.beans.factory.support.DefaultListableBeanFactory#beanDefinitionMap
-
BeanDefinitionRegistry中维护了BeanDefinition#
BeanDefinitionRegistry中维护了BeanDefinition,在BeanDefinitionRegistry中有对BeanDefinition的注册,删除,获取;
// 注册BeanDefinition
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;
// 删除BeanDefinition
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 获取BeanDefinition
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
BeanDefinitionRegistry使用
对于BeanDefinition加载到容器有加载完成与加载未完成的时机,如果使用者需要修改BeanDefinition,那最好是在BeanDefinition加载到Spring容器完成时触发,BeanFactoryPostProcessor这个后置处理器则是在容器加载完BeanDefinition,实例化对象之前,对注册到容器的BeanDefinition所保存的信息做相应的修改;
查看代码
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
查看代码
public class RemoveBeanDefinitionPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 获取IOC容器中的所有BeanDefinition
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
// 判断BeanDefinition对应的Bean是否为Person类型
BeanDefinition beanDefinition = beanFactory
.getBeanDefinition(beanDefinitionName);
if (Person.class.getName().equals(beanDefinition.getBeanClassName())) {
TypedStringValue name = (TypedStringValue) beanDefinition
.getPropertyValues().get("name");
if ("user1".equals(name.getValue())) {
// 移除BeanDefinition
registry.removeBeanDefinition(beanDefinitionName);
}
}
}
}
}
查看代码
public class BeanDefinitionRegistryApplication {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
Person person = ctx.getBean(Person.class);
System.out.println(person);
}
}
查看代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="person1" class="org.example.bean.Person">
<property name="name" value="user1"/>
</bean>
<bean id="person2" class="org.example.bean.Person">
<property name="name" value="user2"/>
</bean>
<bean id="removeBeanDefinitionPostProcessor" class="org.example.bean.RemoveBeanDefinitionPostProcessor"/>
</beans>
执行结果如下:
在BeanFactory的后置处理器移除了user1的beanDefinition;
BeanDefinitionRegistry可用于支撑其他组件的运行#
BeanDefinitionRegistry可用于支撑其他组件的运行,换句话的意思是别的组件的处理逻辑需要依赖BeanDefinitionRegistry;
如ImportBeanDefinitionRegistrar编程式地向Spring容器中导入BeanDefiniton;
其中,@Import注解能够能够导入ImportBeanDefinitionRegistrar的实现类(@Import注解能够导入配置类,ImportSelector的实现类,ImportBeanDefinitionRegistrar的实现类,普通类),如下;
ImportBeanDefinitionRegistrar使用#
查看代码
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
查看代码
public class PersonRegister implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
registry.registerBeanDefinition("person",
BeanDefinitionBuilder.genericBeanDefinition(Person.class)
.addPropertyValue("name", "user1").getBeanDefinition());
}
}
其中,BeanDefinitionBuilder是可以创建GenericBeanDefinition,RootBeanDefinition,ChildBeanDefinition;
查看代码
@Configuration
@Import(PersonRegister.class)
public class BeanDefinitionRegistryConfiguration {
}
查看代码
public class BeanDefinitionRegistryApplication {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
BeanDefinitionRegistryConfiguration.class);
Person person = ctx.getBean(Person.class);
System.out.println(person);
}
}
执行结果如下:
控制台能够打印Person的name属性,即Person对象的BeanDefinition信息通过ImportBeanDefinitionRegistrar注册到Spring容器,Spring容器通过这些BeanDefinition信息创建对应的Bean实例;
注:
ConfigurableListableBeanFactory接口的默认实现是DefaultListableBeanFactory,同时DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,DefaultListableBeanFactory是BeanDefinitionRegistry的主要实现;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能