spring-BeanDefinition-invokeBeanFactoryPostProcessors源码阅读

81 阅读9分钟
  • 如何将一个类的实例对象bean交由spring管理(注意是一个实例对象而不是一个类)

    • 通过@Bean注解

    • 通过FactoryBean实现(实现FactoryBean接口,重写FactoryBean.getObject方法)

      • 一个FactoryBean可以产生两个对象,一个是FactoryBean本身,另一个是通过FactoryBean.getObject方法获取到的bean对象;
      • 在Spring启动时时会对Bean进行初始化创建,当一个Bean实现了另一个是通过FactoryBean时,会根据 "&" + beanName去创建当前FactoryBean的bean对象,然后通过beanName去创建bean时会调用FactoryBean的getObject方法返回我们自己初始化的对象;
        @Component
        public class MyFactoryBean implements FactoryBean {
        
        
            @Override
            public Object getObject() throws Exception {
                TestDemo testDemo = new TestDemo();
                return testDemo;
            }
        
            @Override
            public Class<?> getObjectType() {
                return TestDemo.class;
            }
        }
        
    • 调用spring的api手动注入 beanFactory.registerSingleton(String name,Object object)——直接传自己的对象

      • 通过获取ApplicationContext实例对象,通过向BeanFactory对象中的一级缓存单例池中注入一个bean完成;
        AnnotationConfigApplicationContext applicationContext
                = new AnnotationConfigApplicationContext();
        applicationContext.register(SpringConfig.class);
        
        applicationContext.getBeanFactory().registerSingleton("b",new MyService());
        applicationContext.refresh();
        MyService myService = applicationContext.getBean(MyService.class);
        myService.printInfo();
        
  • spring中的bean和普通的java对象有什么区别,什么是BeanDefinition?

    1711377309290.jpg

    • 在spring框架中,Beandefition是spring容器中对bean抽象定义和描述的元数据;它包含了对应bean在初始化时所需要相关信息,比如bean的名称,类型,生命周期等;在spring中bean的创建和BeanDefition对象相关,与bean对应的class类无关;(可以通过修改beanDefinition中BeanClass从而修改bean的类型);spring会将所有的Bean对应的BeanDefinitiond对象放入在一个BeanFactory中的beanDefinitionMap中;

    • Beandefinition类中几个重要的属性
      • ConstructorArgumentValues=[];主要用于存储对应beanClass构造方法需要传入的参数列表
      • scope: 该bean实例化后的类型,默认为singleton 单例bean;
      • layzInit=false;是否为懒加载的
      • Object beanClass; 该beandefinition是用来创建哪一个类类型的;
      • MutablePropertyValues propertyValues 当前bean依赖注入需要进行属性填充的属性对应值列表(key-value)
      • 其他属性
    • 如何实现手动往spring容器注入一个BeanDefinition
      • 通过BeanFactoryPostProcessor
      • 通过BeanDefinitionRegistryPostProcessor
      • 通过ImportBeanDefinitionRegistrar
  • 什么是BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor它们的工作原理是什么

    • BeanFactoryPostProcessor是BeanFactory的后置处理器,是spring扩展点之一,它允许我们在 Spring容器初始化启动过程中允许程序员对BeanFactory组件进行全局设置,修改,添加beanDefition;设置忽略某个类型,某个接口等功能。
    • BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,它也是spring扩展点之一,并且他的执行时机会比BeanFactoryPostProcessor靠前一点;所以侧重于动态添加BeanDefition对象到容器中
    • BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,但二者都能向容器添加BeanDefinition对象;但由于spring容器初始化顺序的时机不同(如果在bean的扫描之后添加),会导致BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcesso添加的BeanDefinition对象是一个普通bean并且是个不完整的bean,可能存在某种未知的错误;
  • BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor两者的执行顺序(invokeBeanFactoryPostProcessor方法执行BeanFactory的后置处理器)

    • 先说结论:在beanFactory后置处理器中执行顺序

      • 1.首先执行api手动注册的BeanDefinitionRegistryPostProcessor的子类postProcessBeanDefinitionRegistry方法;

      • 2.在执行扫描出来的BeanDefinitionRegistryPostProcessor,按照优先级PriorityOrdered > Order > 二者都未实现的顺序执行postProcessBeanDefinitionRegistry方法;

      • 3.执行所有子类BeanDefinitionRegistryPostProcessor的父类中postProcessBeanFactory方法

      • 4.执行API手动注册的BeanFactoryPostProcessor的postProcessBeanFactory方法

      • 5.最后执行扫描出来的BeanFactoryPostProcessor列表,按照优先级PriorityOrdered > Order > 二者都未实现的顺序执行postProcessBeanFactory方法;

      • 所以由于BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor执行的顺序时机不对,可能会出现注入的bean是个残次品,会出现某种未知的异常;(例如在ConfigurationClassPostProcessor执行之后扫描到的,就无法完成spring中的渲染)

    spring-源码阅读.png

    public static void invokeBeanFactoryPostProcessors(
                ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
            //存放已经处理完的BeanFactoryPostProcessor以及子类BeanDefinitionRegistryPostProcessor,防止重复执行;
            //不会存储通过api提供的,
            Set<String> processedBeans = new HashSet<>();
    
            if (beanFactory instanceof BeanDefinitionRegistry) {
                BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    
                //存放所有实现了BeanFactoryPostProcessor的bean
                List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
    
                //存放所有实现了BeanDefinitionRegistryPostProcessor的bean;
                List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    
                for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    
                    //判断api手动注入的是否是BeanDefinitionRegistryPostProcessor
                    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                        BeanDefinitionRegistryPostProcessor registryProcessor =
                                (BeanDefinitionRegistryPostProcessor) postProcessor;
    
                        //执行api手动注入BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法      
                        registryProcessor.postProcessBeanDefinitionRegistry(registry);
                        registryProcessors.add(registryProcessor);
                    }
                    else {
                        regularPostProcessors.add(postProcessor);
                    }
                }
    
                //当前需要执行的BeanDefinitionRegistryPostProcessor列表
                List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    
                //第一次查找,根据类型去BeanFactory中的BeanDefinitionMap与单例池(spring内置的bean)中去查找,返回名字
                String[] postProcessorNames =
                        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    
    
                for (String ppName : postProcessorNames) {
    
                    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                        //判断是否实现PriorityOrdered接口,是的话调用beanFactory.getBean获取该类的对象(不存在会自动实例化并放入单例池中SingeltonObjects)
                        //放入当前需要执行的currentRegistryProcessors列表中
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        //表示当前类执行完了
                        processedBeans.add(ppName);
                    }
                }
                //排序,order接口和类名等排序
                sortPostProcessors(currentRegistryProcessors, beanFactory);
    
                //合并BeanDefinitionRegistryPostProcessor列表,为了将来执行BeanDefinitionRegistryPostProcessor继承的父类BeanFactoryPostProcessor中的方法
                registryProcessors.addAll(currentRegistryProcessors);
    
    
                //遍历列表,执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry子类方法
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
    
                //清空当前执行BeanDefinitionRegistryPostProcessor列表,因为下次需要继续使用
                currentRegistryProcessors.clear();
    
                //第二次查找,根据类型查找BeanDefinitionRegistryPostProcessor,容器在第一次扫描后,执行完内置BeanDefinitionRegistryPostProcessor(ConfigruationClassPostProcessor完成了spring的扫描),容器中可能会新增了一些BeanDefinitionRegistryPostProcessor;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    
                for (String ppName : postProcessorNames) {
    
                    //判断扫描出来的,是否已经执行过了并且是否实现了Ordered接口
                    if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
    
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
                //排序
                sortPostProcessors(currentRegistryProcessors, beanFactory);
    
                //合并
                registryProcessors.addAll(currentRegistryProcessors);
    
                //遍历执行
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
    
                //清空
                currentRegistryProcessors.clear();
    
                //循环退出标志
                boolean reiterate = true;
    
    
                while (reiterate) {
                    reiterate = false;
    
                    //第三次或n次进行查找,根据类型查找BeanDefinitionRegistryPostProcessor;因为在第二次查找中BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry方法动态添加的BeanDefinitionRegistryPostProcessor的(未被扫描到的);在第二次查找时,可能存在未被执行的BeanDefinitionRegistryPostProcessor(未实现Ordered接口的)
                    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    
                    for (String ppName : postProcessorNames) {
                        if (!processedBeans.contains(ppName)) {
    
                            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                            processedBeans.add(ppName);
    
                            //如果找到了,就得继续找,有可能会有新增
                            reiterate = true;
                        }
                    }
                    sortPostProcessors(currentRegistryProcessors, beanFactory);
                    registryProcessors.addAll(currentRegistryProcessors);
                    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
                    currentRegistryProcessors.clear();
                }
    
                //遍历执行BeanDefinitionRegistryPostProcessor中父类的BeanFactoryPostProcessor的postProcessBeanFactory方法;(因为所有的BeanDefinitionRegistryPostProcessor中的子类方法已经执行完了)
                invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
    
    
                //遍历执行通过Api提供的BeanFactoryPostProcessor的postProcessBeanFactory方法
                invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
            }
    
            else {
                invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
            }
    
    
            //查找不是通过API提供的BeanFactoryPostProcessor列表
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
            //存放实现了priorityOrdered接口的BeanFactoryPostProcessor列表
            List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    
            //存放实现了ordered接口BeanFactoryPostProcessor列表(PriorityOrdered继承了ordered接口)
            List<String> orderedPostProcessorNames = new ArrayList<>();
    
    
            //存放未实现ordered接口和priorityOrdered接口的BeanFactoryPostProcessor列表
            List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    
            for (String ppName : postProcessorNames) {
    
                if (processedBeans.contains(ppName)) {
                    //判断是否执行
                }
                else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    
                    //判断是否实现了PriorityOrdered接口,如果实现了实例化并放入priorityOrderedPostProcessors列表中
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
                }
                else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    //判断是否实现Ordered,是的话放入orderedPostProcessorNames列表,但未进行实例化
                    orderedPostProcessorNames.add(ppName);
                }
                else {
                    nonOrderedPostProcessorNames.add(ppName);
                }
            }
    
            //排序
            sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
            //第一,首先遍历执行已经实现了priorityOrdered接口的BeanFactoryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
    
            List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
            for (String postProcessorName : orderedPostProcessorNames) {
    
                //再遍历创建已经实现ordered接口的BeanFactoryPostProcessor对象
                orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    
            }
    
            sortPostProcessors(orderedPostProcessors, beanFactory);
    
            //第二,遍历执行已经实现了Ordered接口的BeanFactoryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
    
            List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
            for (String postProcessorName : nonOrderedPostProcessorNames) {
                //最后,执行创建未实现ordered接口和priorityOrdered接口的BeanFactoryPostProcessor
                nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
    
            //最后,遍历执行未实现了Ordered接口的BeanFactoryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    
    
            beanFactory.clearMetadataCache();
        }
    
  • BeanFactoryPostProcessor中实现在自动注入模式下忽略某个类型的注入

    • void ignoreDependencyType(Class<?> type);在自动注入的模型下忽略type类型bean的注入,对所有bean都生效;

    • void ignoreDependencyInterface(Class<?> ifc);一般情况下ifc是个接口并且ifc里面有一个setter方法;如果某个bean实现了 ifc接口,那么必然会重写里面的setter,而重写的这个setter就不会被自动注入;主要作用也是忽略某个类型的bean的自动注入;但是ignoreDependencyInterface不能对所有bean生效,你得实现ifc接口才能对忽略的设置生效;(例如spring中aware接口)

    @Slf4j
    public class A implements BeanFactoryPostProcessor {
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            log.error("A类 - BeanFactoryPostProcessor.postProcessBeanFactory()");
            beanFactory.ignoreDependencyType(B.class);
            beanFactory.ignoreDependencyInterface(K.class);
        }
    }
    
  • 如何确保postProcessBeanDefinitionRegistry方法对BeanDefinitionRegistryPostProcessor类型的beanDefition的修改最大化生效

    • 同级别BeanDefinitionRegistryPostProcessor修改一个BeanDefinitionRegistryPostProcessor的beanDefition会失效(对普通类的修改不会失效),因为spring是找出同级别的bean直接实例化存到集合当中,然后一起执行,这样在执行第一个的时候如果修改了第二个的bd则无效;但是对普通类的修改就不会失效了,因为普通类实例化特别靠后,你修改一定会生效;如果你一定需要修改一个BeanDefinitionRegistryPostProcessor对应的的BeanDefition,最好提高当前子类的级别优先级(PriorityOrdered > order > 无接口实现);
  • mybatis是怎么和spring进行整合的?是如何将Mapper代理对象MapperProxy交由spring容器中的

    • mybatis提供一了一个mybatis-spring的插件包实现了与spring的整合。2.0插件包通过MapperScan注解将MapperScannerRegistrar(实现了ImportBeanDefinitionRegistrar接口)中注入一个MapperScannerConfigurer(实现了BeanDefinitionRegistryPostProcessor)的BeanDefition对象,在spring容器初始化过程中会调用ImportBeanDefinitionRegistrar.registerBeanDefinitions方法后,将扫描到的Mapper对于的beanDefition对象就行修改,将beanClass设置成MapperFactoryBean(实现了FactoryBean),并将当前bean的beanclass对象设置成ConstructorArgumentValues中的属性值;最后将该BeanDefinition的注入模式设置为AbstractBeanDefinition.AUTOWIRE_BY_TYPE;
    • mybatis-spring为什么采用ImportBeanDefinitionRegistrar来实现扩展,而不直接使用BeanDefinitionRegistryPostProcessor来完成spring的整合;
      • ImportBeanDefinitionRegistrar.registerBeanDefinitions的执行时机比较靠前,在ConfigurationClassPostProcessor中spring内置的BeanDefinitionRegistryPostProcessor实现了PriortyOrdered接口完成了ImportBeanDefinitionRegistrar的调用,执行完后还能spring还能完成bean的渲染;所以生成的bean是一个功能完整的bean;
      • ImportBeanDefinitionRegistrar.registerBeanDefinitions可以将MapperScan注解的元数据信息给到Mybatis,从而实现用户自定义配置mybatis配置信息;
  • spring中的容器BeanFactory与ApplicationContext?两者的区别是什么,BeanFactory与FactoryBean的区别是什么?

    企业微信截图_1711522826912.png

    • spring框架中存在多种容器,大致可以分为两种BeanFactory与ApplicationContext;spring官网描述说通常情况建议使用ApplicationContext而不是BeanFactory;因为ApplicationContext的功能比BeanFactory更加强大和完善;
      • 两者都支持bean的实例化
        • BeanFactory也能完成bean的实例化,bean的依赖,但是得通过调用getBean方法才会去创建(可以说是懒加载的),而ApplicationContext会自动创建非懒加载的bean;
      • BeanFactory不支持生命周期管理
      • BeanFactory不支持自动注册BeanPostProcessor和自动注册BeanFactoryPostProcessor
      • BeanFactory不支持国际化和不支持事件发布