Spring进阶篇(4)- BeanDefinitionRegistryPostProcessor(操纵Bean对象)

JAVA && Spring && SpringBoot2.x — 学习目录

Spring支持我们通过代码来将指定的类注册到spring容器中。其本质就是一个钩子方法。Spring源码会执行我们自定义的类,来进行对IOC容器中bean对象的增删改查。

(1)org.springframework.context.support.AbstractApplicationContext#refresh方法中,调用了invokeBeanFactoryPostProcessors()方法,BeanFactory的后置处理器,这些后处理器是在Bean定义时向容器中注册的。

(2)通过invokeBeanFactoryPostProcessors() 普瑞赛色方法找出所有的BeanFactory的后置处理器(即BeanFactoryPostProcessor接口实现类),并且调用这些处理器来改变bean的定义。

(3)BeanDefinitionRegistryPostProcessor实现了BeanFactoryPostProcessor接口,可以改变bean的定义,并且可以进行对bean进行注册和删除。

BeanDefinitionRegistryPostProcessor的定义:

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
//1. 继承 BeanFactoryPostProcessor的postProcessBeanFactory方法,可以改变Bean的定义


//2. postProcessBeanDefinitionRegistry方法可以注册、移除Bean到IOC容器中
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}

2. 实战

1. 普通Bean类:

@Data
@Slf4j
public class Student {

    private String id;
    private String name;

    public void init(){
        log.info("【这是初始化方法...】");
    }
}

2. 实现BeanDefinitionRegistryPostProcessor接口的类:

@Component
@Slf4j
public class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {


    public MyBeanFactoryPostProcessor() {
        log.info("【开始执行 BeanFactoryPostProcessor】");
    }


    /**
     * 动态修改Bean信息
     *
     * @param beanFactory
     * @throws BeansException
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        log.info("【修改Bean对象】");
        //获取Controller注解的Bean对象
        //获取BeanDefinition对象
        BeanDefinition student = beanFactory.getBeanDefinition("student1");
        //动态的修改属性值
        student.getPropertyValues().add("name", "tom002");
    }

    /**
     * 动态注册Bean信息
     *
     * @param registry
     * @throws BeansException
     */
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        log.info("【注册Bean对象】");
        BeanDefinition beanDefinition = BeanDefinitionBuilder.
                genericBeanDefinition(Student.class).
                addPropertyValue("id", "001").
                addPropertyValue("name", "tom001")
                .setInitMethodName("init")
                .setScope(BeanDefinition.SCOPE_SINGLETON)
                .getBeanDefinition();

        //普通方法创建BeanDefinition对象
      /*  BeanDefinition beanDefinition = new GenericBeanDefinition();
        //注册信息
        beanDefinition.setBeanClassName("com.processor.Student");
        //设置属性(设置对象的属性值)
        beanDefinition.getPropertyValues().add("id", "001");
        beanDefinition.getPropertyValues().add("name", "tom");*/
        //注册到容器中

        registry.registerBeanDefinition("student1", beanDefinition);
    }
}

BeanDefinition定义了Bean在IOC容器中的基本数据结构,BeanDefinition描述了一个Bean实例,包括属性值,构造方法参数值和继承自它的类的信息。在Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构存储。

BeanDefinition一般用于允许BeanFactoryPostProcessor接口的实现类检索和修改Bean属性值和别的Bean的元数据。

推荐阅读

spring之IOC容器BeanDefinition(bean定义模型)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。