美文网首页
spring源码-invokeBeanFactoryPostPr

spring源码-invokeBeanFactoryPostPr

作者: 王侦 | 来源:发表于2023-01-02 17:31 被阅读0次

在这两个方法执行之前,已经做了如下操作:

  • 创建了DefaultListableBeanFactory
  • beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
  • new RootBeanDefinition(ConfigurationClassPostProcessor.class)
  • new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class)
  • new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)
  • beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this))
  • beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this))

1.invokeBeanFactoryPostProcessors()

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(AppConfig.class);
context.addBeanFactoryPostProcessor(new XXXBeanFactoryPostProcessor);
contest.refresh();
    public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
        return this.beanFactoryPostProcessors;
    }

这里this.beanFactoryPostProcessors就是通过context.addBeanFactoryPostProcessor()手动添加的,如果没有添加,就为空。

invokeBeanFactoryPostProcessors()执行流程:

  • 1)执行通过ApplicationContext手动添加进来的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
  • 2)执行BeanFactory中实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法。这里会将ConfigurationClassPostProcessor的BeanDefinition实例化出来,并进行调用。
  • 3)执行BeanFactory中实现了Ordered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
  • 4)执行BeanFactory中其他的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法(这里是个循环,如果新注册了BeanDefinitionRegistryPostProcessor,会继续循环进行处理)
  • 5)执行上面所有的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法
  • 6)执行通过ApplicationContext手动添加进来的BeanFactoryPostProcessor的postProcessBeanFactory()方法
  • 7)执行BeanFactory中实现了PriorityOrdered接口的BeanFactoryPostProcessor的postProcessBeanFactory()方法
  • 8)执行BeanFactory中实现了Ordered接口的BeanFactoryPostProcessor的postProcessBeanFactory()方法
  • 9)执行BeanFactory中其他的BeanFactoryPostProcessor的postProcessBeanFactory()方法

1.1 ConfigurationClassPostProcessor

1.1.1 processConfigBeanDefinitions()

执行流程:

  • 1)拿到beanFactory容器里面注册的BeanDefinitions,这里只能拿到传入的配置类(这是重点)以及系统自己注册的那些BeanDefinition(ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor等)
  • 2)判断这些BD,哪些是配置类。
    Full配置类:@Configuration注解。
    Lite配置类:@Configuration注解,其proxyBeanMethods为false;有注解@Component、@ComponentScan、@Import、@ImportResource;类里面有加了@Bean注解的方法。
  • 3)对配置类进行排序
  • 4)do ... while(!candidates.isEmpty()) 进行循环解析
  • 4-1)parser.parse(candidates),parser是ConfigurationClassParser
       A)for循环解析candidates
       A-1)this.conditionEvaluator.shouldSkip()处理@Conditional条件注解
       A-2)do...while(sourceClass != null)处理doProcessConfigurationClass,这里循环处理父类
          a)@Component注解,处理内部类
          b)@PropertySource注解,属性配置文件
          c)@ComponentScan、@ComponentScans会构造扫描器进行扫描,遍历扫描得到的BD是否是配置类并进行处理
          d)@Import(三种情况:ImportSelector、ImportBeanDefinitionRegistrar、普通的类(直接当作配置类)),其中DeferredImportSelector,this.deferredImportSelectorHandler.handle()这里只是存了一下。
          e)@ImportResource,导入一个xml配置文件
          f)@Bean方法
          g)处理实现的接口里面的@Bean的default方法
       A-3)this.configurationClasses.put(configClass, configClass)
       B)this.deferredImportSelectorHandler.process();在本轮配置类解析完之后再执行延迟的DeferredImportSelector。
  • 4-2)this.reader.loadBeanDefinitions(configClasses); (生成很多BeanDefinition)将被导入的类@Import以及@Component内部类生成BD注册到Spring容器中;处理@Bean生成的BD;处理@ImportResource导入的xml配置文件;处理@Import导入的ImportBeanDefinitionRegistrar
  • 4-3)筛选出新增的BeanDefinition,并筛选出没有被解析的配置类继续进行处理。@Bean引入的类,其className为null,会判定其不是配置类。

BeanDefinition的覆盖问题:

  • 1)@Component覆盖@Component,对应的名字相同,会抛异常ConflictingBeanDefinitionException:ClassPathBeanDefinitionScanner#checkCandidate。
  • 2)@Bean覆盖@Bean,比如多个重载方法(参数个数不同),不会报错。ConfigurationClassBeanDefinitionReader#isOverriddenByExistingDefinition(),如果相同,则直接返回不会创建新的BD。
  • 3)@Bean覆盖@Component(先扫描,再处理@Bean),如果允许覆盖(默认允许),则@Bean的BD会覆盖@Component的BD。

1.1.2 postProcessBeanFactory()

处理流程:

  • 1)这里会将是Full配置类的BeanDefinition筛选出来
  • 2)对这些Full配置类,生成代理类,并将beanDef.setBeanClass(enhancedClass)的类设置为代理类

这里代理类的增强逻辑是:

    private static final Callback[] CALLBACKS = new Callback[] {
            new BeanMethodInterceptor(),
            new BeanFactoryAwareMethodInterceptor(),
            NoOp.INSTANCE
    };

核心是BeanMethodInterceptor,这里会进行处理下面的问题。

@Configuration
public class AppConfig {
    @Bean
    public UserService userService() {
        System.out.println(orderService());
        System.out.println(orderService());
        return new UserService();
    }

    @Bean
    public OrderService orderService() {
        return new OrderService();
    }
}

这里主要解决的就是上面的这种问题,就是上面的orderService()返回的是同一个对象还是不同对象?如果是Full配置类,则返回的是相同对象,如果不是Full配置类,则返回的是不同的对象。

这里的orderService()除了上面在userService()中调用,还在创建@Bean的单例时会调用。

2.registerBeanPostProcessors()

上面的步骤完成了扫描(这个过程中会扫描出程序员可自己定义的BeanPostProcessor),在这一步就会把BeanFactory中所有的BeanPostProcessor找出来并实例化得到一个对象,并添加到BeanFactory中去(属性beanPostProcessors),最后再重新添加一个ApplicationListenerDetector对象(之前其实就添加了过,这里是为了把ApplicationListenerDetector移动到最后)。

步骤:

  • 1)首先实例化并注册(放到容器的属性beanPostProcessors:CopyOnWriteArrayList)PriorityOrdered的BeanPostProcessor,如果是MergedBeanDefinitionPostProcessor,则将其加入到internalPostProcessors
  • 2)其次实例化并注册Ordered的BeanPostProcessor,如果是MergedBeanDefinitionPostProcessor,则将其加入到internalPostProcessors
  • 3)其他的BeanPostProcessor,如果是MergedBeanDefinitionPostProcessor,则将其加入到internalPostProcessors
  • 4)注册internalPostProcessors,也即将internalPostProcessors移到末尾
  • 5)最后再添加ApplicationListenerDetector

MergedBeanDefinitionPostProcessor表示系统内部的BeanPostProcessor,比如AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor就实现了该接口。

相关文章

网友评论

      本文标题:spring源码-invokeBeanFactoryPostPr

      本文链接:https://www.haomeiwen.com/subject/sqjccdtx.html