ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring的BeanDefinitionRegistry接口

2022-07-31 16:32:14  阅读:68  来源: 互联网

标签:name Person Spring 接口 String BeanDefinitionRegistry public BeanDefinition


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的主要实现;

标签:name,Person,Spring,接口,String,BeanDefinitionRegistry,public,BeanDefinition
来源: https://www.cnblogs.com/coder-zyc/p/16519405.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有