前言通过这篇文章来大家分享一下,另外一个Springboot的扩展点BeanDefinitionRegistryPostProcessor,一般称这类扩展点为容器级后置处理器,另外一类是Bean级的后置处理器;容器级的后置处理器会在Spring容器初始化后、刷新前这个时间执行一次,Bean级的后置处理器,则是在每一个Bean实例化前后都会执行 。
![Springboot扩展点之BeanDefinitionRegistryPostProcessor,你学会了吗?](http://img.jiangsulong.com/231127/16431560X-0.jpg)
文章插图
功能特性
- postProcessBeanDefinitionRegistry()方法 可以通过BeanDefinitionRegistry对BeanDefintion进行增删改查;
- 继承了BeanFactoryPostProcessor,BeanFactoryPostProcessor是容器级别的扩展接口,org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory方法在容器实例化后、刷新容器前被执行,即在容器刷新前还可以对BeanDefintion再作一些操作;
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;}
@FunctionalInterfacepublic interface BeanFactoryPostProcessor {void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;}
总结起来就是,在所有的BeanDefinition加载完成之后,Bean真正被实例化之前,可以通过实现BeanDefinitionRegistryPostProcessor接口,对BeanDefinition再做一些定制化的操作,比如修改某个bean的BeanDefinition的属性、手动注册一些复杂的Bean 。对于Spring原理不太熟悉的小伙伴心里看到这可能有点晕了 , BeanDefinition是什么?BeanDefinitionRegistry又是什么?ConfigurableListableBeanFactory又又是什么?别着急,这里拐个弯简单的解释一下,方便下面的内容理解起来更顺畅 。
BeanDefinition大家都知道,Spring的核心之一是IOC(控制反转),Spring之所以可以实现bean控制权的反转 , 是因为Spring的容器功能,在bean纳入Spring容器管理前,所有bean会被抽象封装成一个BeanDefinition实例 , 然后会在不同的时机根据BeanDefinition实例信息对bean进行实例化 。
简单说,Dog.JAVA描述狗这一类动物的属性和行为,BeanDefinition描述Dog.java这个类 。
BeanDefinitionRegistryBeanDefinitionRegistry从字面意思看是bean的定义信息的注册登记 , 其实这个类的功能和字面意思一样,就是对BeanDefinition进行管理(增删改查);
public interface BeanDefinitionRegistry extends AliasRegistry {//注册beanDefinitionvoid registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException;//移除指定的beanDefinitionvoid removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;//根据beanName查询beanDefinitionBeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;//判断某个beanDefinition是否已经注册boolean contAInsBeanDefinition(String beanName);//获取所有已注册的beanDefinitionString[] getBeanDefinitionNames();//获取所有已注册的beanDefinition的数量int getBeanDefinitionCount();//判断某个beanDefinition是否已经被使用boolean isBeanNameInUse(String beanName);}
ConfigurableListableBeanFactory上面提到了Spring的容器,Spring的核心之一是IOC,那么Spring的容器设计就是核心中的核心了 。Spring的容器有多种形态,最基础的形态就是BeanFactory , ConfigurableListableBeanFactory间接继承了BeanFactory,因此ConfigurableListableBeanFactory实现类除了有Spring基础版本容器的功能外,还有一些高级的功能,Springboot默认的实际实现是DefaultListableBeanFactory,有兴趣的小伙伴可以以此为入口深入探究一番 , 这里不展开细说了 。![Springboot扩展点之BeanDefinitionRegistryPostProcessor,你学会了吗?](http://img.jiangsulong.com/231127/164315EZ-1.jpg)
文章插图
自定义实现MyBeanDefinitionRegistryPostProcessor下面通过一个具体类MyBeanDefinitionRegistryPostProcessor实现BeanDefinitionRegistryPostProcessor接口,来探究BeanDefinitionRegistryPostProcessor实现类的初始化和执行过程 。
- 在postProcessBeanDefinitionRegistry()方法被调用的时候手工在Spring中注册了Dog类的BeanDefinition信息;
- 在postProcessBeanFactory()方法被调用的时候,从Spring容器中取出Dog类的BeanDefinition信息和Dog类的实例;
@Datapublic class Dog {private String name;private String color;}
@Componentpublic class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {//手工定义一个beanDefinition实例RootBeanDefinition beanDefinition = new RootBeanDefinition();//给beanDefinition填充属性beanDefinition.setBeanClass(Dog.class);MutablePropertyValues propertyValues = new MutablePropertyValues();PropertyValue propertyValue1 = new PropertyValue("name", "旺财");PropertyValue propertyValue2 = new PropertyValue("color", "黑色");propertyValues.addPropertyValue(propertyValue1);propertyValues.addPropertyValue(propertyValue2);beanDefinition.setPropertyValues(propertyValues);//注册手工定义的beanDefinitionregistry.registerBeanDefinition("dog", beanDefinition);}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("-----------start------------");//根据类名取出手工注册的beanDefinitionBeanDefinition beanDefinition = beanFactory.getBeanDefinition("dog");System.out.println(beanDefinition.getBeanClassName());//根据类从容器中取出手工注册的beanDefinition所描述的实例beanDog dog = beanFactory.getBean(Dog.class);System.out.println(dog.getName());System.out.println(dog.getColor());System.out.println("-----------end------------");}}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- wps文档的扩展名是什么
- 九个AI增强开发效率的VSCode扩展插件
- Spring Event 业务解耦神器,大大提高可扩展性,刷爆了!
- 子时是几点钟,子时是几点到几点之间
- 电脑扩展屏幕能咋的操作
- 电脑应该咋才能扩展屏幕,双屏只能扩展不能复制屏幕
- SpringBoot整合ElasticSearch详解及相关使用方法
- 利用Docker简化机器学习应用程序的部署和可扩展性
- 电脑扩展屏幕能咋样操作
- Springboot之把外部依赖包纳入Spring容器管理的两种方式