Spring源码分析之扩展点BeanDefinitionRegistryPostProcessor

野性酷女 2023-10-08 08:42 32阅读 0赞

一、BeanDefinitionRegistryPostProcessor接口

  • 简介:该接口继承了BeanFactoryPostProcessor接口,且新增postProcessBeanDefinitionRegistry方法。

方法参数是BeanDefinitionRegistry对象,BeanDefinitionRegistry对象是bean定义的保存中心(实际底层就是BeanDefinitionMap 后续会专门详细介绍)。这里可以简单看下源码,如下图所示。

这里在BeanDefinitionRegistry的子类DefaultListableBeanFactory中,可以看到。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ldmFud2FuZy5ibG9nLmNzZG4ubmV0_size_16_color_FFFFFF_t_70

在时机上,可以理解为该方法与spring容器的初始化扫描同期执行,即(将扫描的bean转化成BeanDefinition,放入到BeanDefinitionMap之前) 这里也可以通过Debug验证。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ldmFud2FuZy5ibG9nLmNzZG4ubmV0_size_16_color_FFFFFF_t_70 1

当执行完这行代码之后,我们可以看到我们自己实现的MyBeanDefinitionRegistryPostProcessor被放入到BeanDefinitionMap中。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ldmFud2FuZy5ibG9nLmNzZG4ubmV0_size_16_color_FFFFFF_t_70 2

  • 作用:作为spring的扩展点,可以实现将自己定义的bean动态的扫描并注册到spring容器当中。

二、类关系结构图

BeanDefinitionRegistryPostProcessor的类关系结构图,如下图所示。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ldmFud2FuZy5ibG9nLmNzZG4ubmV0_size_16_color_FFFFFF_t_70 3

三、代码示例:

  1. package com.evan.config;
  2. import org.springframework.context.annotation.ComponentScan;
  3. @ComponentScan("com.evan")
  4. public class MyConfig {
  5. }
  6. package com.evan.processor;
  7. import com.evan.service.EvanService;
  8. import org.springframework.beans.BeansException;
  9. import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
  10. import org.springframework.beans.factory.support.BeanDefinitionRegistry;
  11. import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
  12. import org.springframework.beans.factory.support.RootBeanDefinition;
  13. import org.springframework.stereotype.Component;
  14. @Component
  15. public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
  16. // --- 此方法在所有BeanDefinition将要被加载(spring初始化本身需要的BeanDefinition除外),它优先于postProcessBeanFactory方法执行。
  17. //作用:可以将自己定义的类动态的加入到spring容器。
  18. @Override
  19. public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
  20. System.out.println("此时的registry中有: " + registry.getBeanDefinitionCount() + " 个BeanDefinition.");
  21. RootBeanDefinition rbd = new RootBeanDefinition(EvanService.class);
  22. registry.registerBeanDefinition("Evan", rbd);
  23. }
  24. //继承自BeanFactoryPostProcessor
  25. // 作用:在bean实例化之前,动态的修改配置BeanDefinition,其实不止是可以修改BeanDefinition,还可以修改beanFactory中的其他信息。
  26. @Override
  27. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
  28. System.out.println("此时的registry中有: " + beanFactory.getBeanDefinitionCount() + " 个BeanDefinition.");
  29. }
  30. }
  31. package com.evan.service;
  32. public class EvanService {
  33. public EvanService() {
  34. System.out.println("EvanService的无参构造执行了!");
  35. }
  36. }
  37. package com.evan.test;
  38. import com.evan.config.MyConfig;
  39. import org.springframework.context.annotation.AnnotationConfigApplicationContext;
  40. public class Test {
  41. public static void main(String[] args) {
  42. AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);
  43. System.out.println(ac.getBeanDefinition("Evan"));
  44. }
  45. }

打印结果:

  1. 此时的registry中有: 7 BeanDefinition.
  2. 此时的registry中有: 8 BeanDefinition.
  3. EvanService的无参构造执行了!
  4. Root bean: class [com.evan.service.EvanService]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null

发表评论

表情:
评论列表 (有 0 条评论,32人围观)

还没有评论,来说两句吧...

相关阅读