Bean实例化之前修改BeanDefinition示例详解

 更新时间:2022年12月26日 15:25:55   作者:刨红薯的小羊竿尔  
这篇文章主要为大家介绍了Bean实例化之前修改BeanDefinition示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

BeanFactory

BeanFactory是Spring中容器功能的基础,用于存放所有已经加载的bean,为了保证程序上的高可扩展性,Spring针对BeanFactory做了大量的扩展。BeanFactoryPostProcessor是BeanFactory的后置处理器;比如在postProcessBeanFactory方法中,可以获取BeanDefinition的相关对象,并且修改该对象的属性。

@FunctionalInterface
public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}

通过BeanDefinition对象实例化Bean对象

Spring IOC在实例化Bean对象之前,需要先读取Bean的相关属性,保存到BeanDefinition对象中,然后通过BeanDefinition对象,实例化Bean对象。如果我们需要修改BeanDefinition对象中的属性,就可以实现BeanFactoryPostProcessor接口,重写postProcessBeanFactory方法进行自定义,是不是很方便呢。

    @Component
    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
            DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
            beanDefinitionBuilder.addPropertyValue("id", 123456);
            beanDefinitionBuilder.addPropertyValue("label", "技术那些事儿");
            defaultListableBeanFactory.registerBeanDefinition("user", beanDefinitionBuilder.getBeanDefinition());
        }
    }

BeanFactoryPostProcessor使用目的:在BeanFactory标准初始化之后调用,用来定制和修改BeanFactory的内容;

BeanFactoryPostProcessor工作时机:所有的bean定义已经保存加载到beanFactory中,但bean的实例还没创建;

BeanFactoryPostProcessor和BeanPostProcessor类似,可以对beanDefinition进行处理,也就是说SpringIOC容器允许BeanFactoryPostProcessor在容器实际实例化任何bean之前读取beanDefinition,并有可能修改它。并且我们还可以配置自定义的BeanFactoryPostProcessor,如果想改变bean,那么使用beanPostProcessor。

并可以通过order属性来控制BeanFactoryPostProcessor的执行次序;因为只有实现了Ordered接口时,才可以设置这个属性,所以在实现BeanFactoryPostProcessor的时候,就应该考虑实现Ordered接口。

BeanFactoryPostProcessor的作用域是容器级的,只和你使用的容器有关,如果在一个容器中定义了一个BeanFactoryPostProcessor,它仅仅对此容器中的beanDefinition进行后处理。BeanFactoryPostProcessor不会对定义在另一个容器中的bean进行后处理,即便这两个容器都在同一个层次上。

BeanFactoryPostProcessor还有一个子接口BeanDefinitionRegistryPostProcessor,其内部添加了一个方法postProcessBeanDefinitionRegistry:

void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

ConfigurationClassPostProcessor这个类非常重要,其实现了BeanDefinitionRegistryPostProcessor接口与PriorityOrdered接口:

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
                PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware 
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
	int registryId = System.identityHashCode(registry);
	if (this.registriesPostProcessed.contains(registryId)) {
		throw new IllegalStateException(
				"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
	}
	if (this.factoriesPostProcessed.contains(registryId)) {
		throw new IllegalStateException(
				"postProcessBeanFactory already called on this post-processor against " + registry);
	}
	this.registriesPostProcessed.add(registryId);
	/**
	 * @author lcy
	 * 处理配置beanDefinition
	 */
	processConfigBeanDefinitions(registry);
}

就是在这个方法里将配置类指定的类解析为BeanDefinition对象,并放入BeanFactory的beanDefinitionMap中。还有一点需要说明,这个类是在执行AnnotationConfigApplicationContext的无参构造方法时被解析为beanDefinition并放入map中的。在AnnotationConfigApplicationContext的refresh()内部的 invokeBeanFactoryPostProcessors(beanFactory)方法完成了对 BeanFactoryPostProcessor对象与BeanDefinitionRegistryPostProcessor对象相关方法的执行。

以上就是Bean实例化之前修改BeanDefinition示例详解的详细内容,更多关于Bean实例化修改BeanDefinition的资料请关注脚本之家其它相关文章!

相关文章

  • 浅析java快速排序算法

    浅析java快速排序算法

    这篇文章主要介绍了浅析java快速排序算法,需要的朋友可以参考下
    2015-02-02
  • MyBatis配置与CRUD超详细讲解

    MyBatis配置与CRUD超详细讲解

    这篇文章主要介绍了MyBatis配置与CRUD,CRUD是指在做计算处理时的增加(Create)、读取(Read)、更新(Update)和删除(Delete)几个单词的首字母简写。CRUD主要被用在描述软件系统中数据库或者持久层的基本操作功能
    2023-02-02
  • SpringBoot Mybatis如何配置多数据源并分包

    SpringBoot Mybatis如何配置多数据源并分包

    这篇文章主要介绍了SpringBoot Mybatis如何配置多数据源并分包,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • JAVA实现JSON后端向前端传递数据

    JAVA实现JSON后端向前端传递数据

    本篇文章主要介绍了JAVA实现JSON后端向前端传递数据,这里整理了详细的代码,具有一定的参考价值,有需要的小伙伴可以参考下。
    2017-03-03
  • Spring自动配置之condition条件判断上篇

    Spring自动配置之condition条件判断上篇

    这篇文章主要为大家介绍了SpringBoot condition条件判断功能的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • SpringBoot整合Tomcat连接池的使用

    SpringBoot整合Tomcat连接池的使用

    这篇文章主要介绍了SpringBoot整合Tomcat连接池的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • SpringBoot实现阿里云快递物流查询的示例代码

    SpringBoot实现阿里云快递物流查询的示例代码

    本文将基于springboot实现快递物流查询,物流信息的获取通过阿里云第三方实现,具有一定的参考价值,感兴趣的可以了解一下
    2021-10-10
  • Spring AOP简介及统一处理

    Spring AOP简介及统一处理

    AOP面向切面编程,它是一种思想,它是对某一类事情的集中处理,本文给大家介绍Spring AOP简介及统一处理,感兴趣的朋友跟随小编一起看看吧
    2023-09-09
  • 基于java实现斗地主代码实例解析

    基于java实现斗地主代码实例解析

    这篇文章主要介绍了基于java实现斗地主代码实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Spring中Bean初始化和销毁的方式总结

    Spring中Bean初始化和销毁的方式总结

    这篇文章主要为大家整理了Spring中Bean初始化和销毁的多种方式,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以了解一下
    2023-04-04

最新评论