Spring核心 - BeanDefinitionRegistryPostProcessor

BeanDefinitionRegistryPostProcessor 基本介绍:

它是Spring框架的一个扩展点,用于对Bean定义的注册过程进行干预和定制。
继承BeanFactoryPostProcessor接口,并在其基础上扩展了一个新的方法,即:postProcessBeanDefinitionRegistry()方法。

BeanDefinitionRegistryPostProcessor 用途:

在Spring容器初始化时,首先会读取应用程序中的配置文件,并解析出所有的Bean定义,然后将这些Bean定义注册到容器中。
在这个过程中,BeanDefinitionRegistryProcessor提供了一种机制,允许开发人员在Bean定义注册之前和之后对Bean定义进行自定义处理,例如添加,修改或删除Bean定义等。

BeanDefinitionRegistryPostProcessor 具体原理:
具体来说,BeanDefinitionRegistryPostProcessor提供了以下两个方法:

postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry):该方法在所有Bean定义加载完成之后,Bean实例化之前被调用,允许开发人员对Bean定义进行自定义修改,例如添加,修改或删除Bean定义等。
postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory): 该方法是继承自BeanFactoryPostProcessor接口的方法,用于在BeanFactory完成实例化之后对BeanFactory进行后置处理。
那么我们通过BeanDefinitionRegistryPostProcessor接口,开发人员可以在Spring容器启动时干预Bean的注册过程,从而实现对Bean的自定义处理。
例如:
可以通过该接口来动态注册Bean定义,从而实现基于注解或者其他方式的自动发现和注册Bean。
同时,该接口也提供了一种扩展点,允许开发人员在Bean定义注册之后再进行后置处理,例如对Bean的属性进行统一设置,验证等操作。

Spring容器初始化时,从资源中读取到bean的相关定义后,保存在BeanDefinitionMap,在实例化bean的操作就是依据这些bean的定义来做的,而在实例化之前,Spring允许我们通过自定义扩展来改变bean的定义,定义一旦变了,后面的实例也就变了,而beanFactory后置处理器,即BeanFactoryPostProcessor就是用来改变bean定义的

BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口,BeanFactoryPostProcessor的实现类在其postProcessBeanFactory方法被调用时,可以对bean的定义进行控制,因此BeanDefinitionRegistryPostProcessor的实现类一共要实现以下两个方法:

void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException:
该方法的实现中,主要用来对bean定义做一些改变。

void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException:
该方法用来注册更多的bean到spring容器中,详细观察入参BeanDefinitionRegistry接口,看看这个参数能带给我们什么能力。

在这里插入图片描述
从BeanDefinitionRegistry可以看到,BeanDefinitionRegistry提供了丰富的方法来操作BeanDefinition,判断、注册、移除等方法都准备好了,我们在编写postProcessBeanDefinitionRegistry方法的内容时,就能直接使用入参registry的这些方法来完成判断和注册、移除等操作。

org.springframework.context.support.AbstractApplicationContext#refresh中的invokeBeanFactoryPostProcessors(beanFactory);用来找出所有beanFactory后置处理器,并且调用这些处理器来改变bean的定义。

invokeBeanFactoryPostProcessors(beanFactory)实际上是委托org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());方法处理的。

所有实现了BeanDefinitionRegistryPostProcessor接口的bean,其postProcessBeanDefinitionRegistry方法都会调用,然后再调用其postProcessBeanFactory方法,这样一来,我们如果自定义了BeanDefinitionRegistryPostProcessor接口的实现类,那么我们开发的postProcessBeanDefinitionRegistry和postProcessBeanFactory方法都会被执行一次

示例代码:

@Component
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;

/**
 * 自定义的BeanDefinitionRegistryPostProcessor
 */
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    /**
     * 重写BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
     */
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        // 创建一个RootBeanDefinition实例,该实例对应的BeanClass是MyBean
        RootBeanDefinition beanDefinition = new RootBeanDefinition(MyBean.class);
        // 向BeanDefinitionRegistry注册MyBean的BeanDefinition
        registry.registerBeanDefinition("myBean", beanDefinition);
    }

    /**
     * 重写BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // do nothing
    }

    /**
     * 自定义的Bean
     */
    public static class MyBean {
        private String message = "Hello, World!";

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }
    }
}

在容器启动时,Spring会自动检测到MyBeanDefinitionRegistryPostProcessor并将其实例化和注册到容器中。在容器启动完成后,我们的myBean就可以在容器中被其他的Bean所依赖和使用了。

总结下,BeanFactoryPostProcessor可以修改各个注册的Bean,BeanDefinitionRegistryPostProcessor可以动态将Bean注册。

小结:BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor提供了在容器实例化之后,在容器中bean的实例化之前对容器进行修改的入口。
它们的区别是BeanDefinitionRegistryPostProcessor针对的是beanRegietry,BeanFactoryPostProcessor修改的是beanfactory。通过这两个接口,可以实现对bean的注册,bean实例化之前属性的修改等操作。例如Spring中的BeanDefinitionRegistryPostProcessor的实现类ConfigurationClassPostProcessor,通过这个类会将Spring中@Configuration、@Import、@Bean等注解的类扫描出来,并封装成BeanDefinition注册进容器中

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值