zoukankan      html  css  js  c++  java
  • Spring笔记(6)

    一.背景

      在说BeanFactoryPostProcessor之前,先来说下BeanPostProcessor,在前文Spring笔记(2) - 生命周期/属性赋值/自动装配及部分源码解析中讲解了BeanPostProcessor是一个bean后置处理器(bean创建对象初始化前后进行拦截工作)。

      BeanPostProcessor的运行流程如下:

        1)Spring IOC容器实例化Bean;

        2)调用BeanPostProcessor的postProcessBeforeInitialization方法;

        3)调用bean实例的初始化方法;

        4)调用BeanPostProcessor的postProcessAfterInitialization方法; 

      实现BeanPostProcessor接口可以在Bean(实例化之后)初始化的前后做一些自定义的操作,但是拿到的参数只有BeanDefinition实例和BeanDefinition的名称,也就是无法修改BeanDefinition元数据,这里说的Bean的初始化是:

        1)bean实现了InitializingBean接口,对应的方法为afterPropertiesSet 

        2)在bean定义的时候,通过init-method设置的方法

      Spring中Bean的实例化过程图示:  


      那么BeanFactoryPostProcessor顾名思义就是bean工厂的后置处理器,说通俗一些就是可以管理我们的bean工厂内所有的BeanDefinition(未实例化)数据,可以随心所欲的修改属性。            

      Spring容器初始化时,从资源中读取到bean的相关定义后,保存在beanFactory的成员变量中(参考DefaultListableBeanFactory类的成员变量beanDefinitionMap),在实例化bean的操作就是依据这些bean的定义来做的,而在实例化之前,Spring允许我们通过自定义扩展来改变bean的定义,定义一旦变了,后面的实例也就变了,而beanFactory后置处理器,即BeanFactoryPostProcessor就是用来改变bean定义的;如果业务需要,可以配置多个BeanFactoryPostProcessor的实现类,通过”order”控制执行次序(要实现Ordered接口)。

      注册一个BeanFactoryPostProcessor实例需要定义一个Java类来实现BeanFactoryPostProcessor接口,并重写该接口的postProcessorBeanFactory方法。通过beanFactory可以获取bean的定义信息,并可以修改bean的定义信息。(这点是和BeanPostProcessor最大区别)

      所以通过上面的介绍可以总结出有两种方式可以对bean做控制(例如修改某个成员变量):

        1. 只改变实例化的对象(BeanPostProcessor接口);

        2. 改变bean的定义(BeanFactoryPostProcessor接口) ,可以想象成修改了class文件,这样实例化出来的每个对象都变了;  

      PS:BeanFactoryPostProcessor回调会先于BeanPostProcessor  

      下面是BeanFactoryPostProcessor的源码:

    public interface BeanFactoryPostProcessor {
    
        /**
         * Modify the application context's internal bean factory after its standard
         * initialization. All bean definitions will have been loaded, but no beans
         * will have been instantiated yet. This allows for overriding or adding
         * properties even to eager-initializing beans.
         * @param beanFactory the bean factory used by the application context
         * @throws org.springframework.beans.BeansException in case of errors
         */
         //在ioc容器的bean Factory标准初始化之后可以对它们进行修改。所有的bean定义被加载了,但还没有被实例化。
         //允许进行重载或添加属性即使在eager-initializing beans
        void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
    
    }

      BeanFactoryPostProcessor此接口只提供了一个方法,方法参数为ConfigurableListableBeanFactory,下面是该类的源码: 

    public interface ConfigurableListableBeanFactory
            extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
    
        void ignoreDependencyType(Class<?> type);
    
        void ignoreDependencyInterface(Class<?> ifc);
    
        void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue);
    
        boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
                throws NoSuchBeanDefinitionException;
    
        BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
    
        Iterator<String> getBeanNamesIterator();
    
        void clearMetadataCache();
    
        void freezeConfiguration();
    
        boolean isConfigurationFrozen();
    
        void preInstantiateSingletons() throws BeansException;
    
    }

      其中有个方法名为getBeanDefinition的方法,我们可以根据此方法,找到我们定义bean的BeanDefinition对象。然后我们可以对定义的属性进行修改,以下是BeanDefinition中的方法:

    public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
    
        /**
         * Scope identifier for the standard singleton scope: "singleton".
         * <p>Note that extended bean factories might support further scopes.
         * @see #setScope
         */
        String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
    
        /**
         * Scope identifier for the standard prototype scope: "prototype".
         * <p>Note that extended bean factories might support further scopes.
         * @see #setScope
         */
        String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
    
    
        /**
         * Role hint indicating that a {@code BeanDefinition} is a major part
         * of the application. Typically corresponds to a user-defined bean.
         */
        int ROLE_APPLICATION = 0;
    
        /**
         * Role hint indicating that a {@code BeanDefinition} is a supporting
         * part of some larger configuration, typically an outer
         * {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
         * {@code SUPPORT} beans are considered important enough to be aware
         * of when looking more closely at a particular
         * {@link org.springframework.beans.factory.parsing.ComponentDefinition},
         * but not when looking at the overall configuration of an application.
         */
        int ROLE_SUPPORT = 1;
    
        /**
         * Role hint indicating that a {@code BeanDefinition} is providing an
         * entirely background role and has no relevance to the end-user. This hint is
         * used when registering beans that are completely part of the internal workings
         * of a {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
         */
        int ROLE_INFRASTRUCTURE = 2;
    
    
        // Modifiable attributes
    
        /**
         * Set the name of the parent definition of this bean definition, if any.
         */
        void setParentName(@Nullable String parentName);
    
        /**
         * Return the name of the parent definition of this bean definition, if any.
         */
        @Nullable
        String getParentName();
    
        /**
         * Specify the bean class name of this bean definition.
         * <p>The class name can be modified during bean factory post-processing,
         * typically replacing the original class name with a parsed variant of it.
         * @see #setParentName
         * @see #setFactoryBeanName
         * @see #setFactoryMethodName
         */
        void setBeanClassName(@Nullable String beanClassName);
    
        /**
         * Return the current bean class name of this bean definition.
         * <p>Note that this does not have to be the actual class name used at runtime, in
         * case of a child definition overriding/inheriting the class name from its parent.
         * Also, this may just be the class that a factory method is called on, or it may
         * even be empty in case of a factory bean reference that a method is called on.
         * Hence, do <i>not</i> consider this to be the definitive bean type at runtime but
         * rather only use it for parsing purposes at the individual bean definition level.
         * @see #getParentName()
         * @see #getFactoryBeanName()
         * @see #getFactoryMethodName()
         */
        @Nullable
        String getBeanClassName();
    
        /**
         * Override the target scope of this bean, specifying a new scope name.
         * @see #SCOPE_SINGLETON
         * @see #SCOPE_PROTOTYPE
         */
        void setScope(@Nullable String scope);
    
        /**
         * Return the name of the current target scope for this bean,
         * or {@code null} if not known yet.
         */
        @Nullable
        String getScope();
    
        /**
         * Set whether this bean should be lazily initialized.
         * <p>If {@code false}, the bean will get instantiated on startup by bean
         * factories that perform eager initialization of singletons.
         */
        void setLazyInit(boolean lazyInit);
    
        /**
         * Return whether this bean should be lazily initialized, i.e. not
         * eagerly instantiated on startup. Only applicable to a singleton bean.
         */
        boolean isLazyInit();
    
        /**
         * Set the names of the beans that this bean depends on being initialized.
         * The bean factory will guarantee that these beans get initialized first.
         */
        void setDependsOn(@Nullable String... dependsOn);
    
        /**
         * Return the bean names that this bean depends on.
         */
        @Nullable
        String[] getDependsOn();
    
        /**
         * Set whether this bean is a candidate for getting autowired into some other bean.
         * <p>Note that this flag is designed to only affect type-based autowiring.
         * It does not affect explicit references by name, which will get resolved even
         * if the specified bean is not marked as an autowire candidate. As a consequence,
         * autowiring by name will nevertheless inject a bean if the name matches.
         */
        void setAutowireCandidate(boolean autowireCandidate);
    
        /**
         * Return whether this bean is a candidate for getting autowired into some other bean.
         */
        boolean isAutowireCandidate();
    
        /**
         * Set whether this bean is a primary autowire candidate.
         * <p>If this value is {@code true} for exactly one bean among multiple
         * matching candidates, it will serve as a tie-breaker.
         */
        void setPrimary(boolean primary);
    
        /**
         * Return whether this bean is a primary autowire candidate.
         */
        boolean isPrimary();
    
        /**
         * Specify the factory bean to use, if any.
         * This the name of the bean to call the specified factory method on.
         * @see #setFactoryMethodName
         */
        void setFactoryBeanName(@Nullable String factoryBeanName);
    
        /**
         * Return the factory bean name, if any.
         */
        @Nullable
        String getFactoryBeanName();
    
        /**
         * Specify a factory method, if any. This method will be invoked with
         * constructor arguments, or with no arguments if none are specified.
         * The method will be invoked on the specified factory bean, if any,
         * or otherwise as a static method on the local bean class.
         * @see #setFactoryBeanName
         * @see #setBeanClassName
         */
        void setFactoryMethodName(@Nullable String factoryMethodName);
    
        /**
         * Return a factory method, if any.
         */
        @Nullable
        String getFactoryMethodName();
    
        /**
         * Return the constructor argument values for this bean.
         * <p>The returned instance can be modified during bean factory post-processing.
         * @return the ConstructorArgumentValues object (never {@code null})
         */
        ConstructorArgumentValues getConstructorArgumentValues();
    
        /**
         * Return if there are constructor argument values defined for this bean.
         * @since 5.0.2
         */
        default boolean hasConstructorArgumentValues() {
            return !getConstructorArgumentValues().isEmpty();
        }
    
        /**
         * Return the property values to be applied to a new instance of the bean.
         * <p>The returned instance can be modified during bean factory post-processing.
         * @return the MutablePropertyValues object (never {@code null})
         */
        MutablePropertyValues getPropertyValues();
    
        /**
         * Return if there are property values values defined for this bean.
         * @since 5.0.2
         */
        default boolean hasPropertyValues() {
            return !getPropertyValues().isEmpty();
        }
    
        /**
         * Set the name of the initializer method.
         * @since 5.1
         */
        void setInitMethodName(@Nullable String initMethodName);
    
        /**
         * Return the name of the initializer method.
         * @since 5.1
         */
        @Nullable
        String getInitMethodName();
    
        /**
         * Set the name of the destroy method.
         * @since 5.1
         */
        void setDestroyMethodName(@Nullable String destroyMethodName);
    
        /**
         * Return the name of the destroy method.
         * @since 5.1
         */
        @Nullable
        String getDestroyMethodName();
    
        /**
         * Set the role hint for this {@code BeanDefinition}. The role hint
         * provides the frameworks as well as tools with an indication of
         * the role and importance of a particular {@code BeanDefinition}.
         * @since 5.1
         * @see #ROLE_APPLICATION
         * @see #ROLE_SUPPORT
         * @see #ROLE_INFRASTRUCTURE
         */
        void setRole(int role);
    
        /**
         * Get the role hint for this {@code BeanDefinition}. The role hint
         * provides the frameworks as well as tools with an indication of
         * the role and importance of a particular {@code BeanDefinition}.
         * @see #ROLE_APPLICATION
         * @see #ROLE_SUPPORT
         * @see #ROLE_INFRASTRUCTURE
         */
        int getRole();
    
        /**
         * Set a human-readable description of this bean definition.
         * @since 5.1
         */
        void setDescription(@Nullable String description);
    
        /**
         * Return a human-readable description of this bean definition.
         */
        @Nullable
        String getDescription();
    
    
        // Read-only attributes
    
        /**
         * Return a resolvable type for this bean definition,
         * based on the bean class or other specific metadata.
         * <p>This is typically fully resolved on a runtime-merged bean definition
         * but not necessarily on a configuration-time definition instance.
         * @return the resolvable type (potentially {@link ResolvableType#NONE})
         * @since 5.2
         * @see ConfigurableBeanFactory#getMergedBeanDefinition
         */
        ResolvableType getResolvableType();
    
        /**
         * Return whether this a <b>Singleton</b>, with a single, shared instance
         * returned on all calls.
         * @see #SCOPE_SINGLETON
         */
        boolean isSingleton();
    
        /**
         * Return whether this a <b>Prototype</b>, with an independent instance
         * returned for each call.
         * @since 3.0
         * @see #SCOPE_PROTOTYPE
         */
        boolean isPrototype();
    
        /**
         * Return whether this bean is "abstract", that is, not meant to be instantiated.
         */
        boolean isAbstract();
    
        /**
         * Return a description of the resource that this bean definition
         * came from (for the purpose of showing context in case of errors).
         */
        @Nullable
        String getResourceDescription();
    
        /**
         * Return the originating BeanDefinition, or {@code null} if none.
         * Allows for retrieving the decorated bean definition, if any.
         * <p>Note that this method returns the immediate originator. Iterate through the
         * originator chain to find the original BeanDefinition as defined by the user.
         */
        @Nullable
        BeanDefinition getOriginatingBeanDefinition();
    
    }
    View Code

      我们可以在上面代码中发现里面的方法名字类似bean标签的属性,setBeanClassName对应bean标签中的class属性,所以当我们拿到BeanDefinition对象时,我们可以手动修改bean标签中所定义的属性值。

      具体这个BeanDefinition是个什么对象,当我们在xml中定义了bean标签时,Spring会把这些bean标签解析成一个javabean,这个BeanDefinition就是bean标签对应的javabean。

      所以当我们调用BeanFactoryPostProcess方法时,这时候bean还没有实例化,此时bean刚被解析成BeanDefinition对象。

      Spring容器初始化bean大致过程 :

        1)定义bean标签

        2)将bean标签解析成BeanDefinition

        3)调用构造方法实例化(IOC)

        4)属性值得依赖注入(DI)

      所以可以看出BeanFactoryPostProcess方法的执行是发生在第二步之后,第三步之前。

      综上所述BeanPostProcessor和BeanFactoryPostProcess都是为Spring提供的后处理bean的接口,只是两者执行的时机不一样。BeanPostProcessor为实例化之后,BeanFactoryPostProcess是实例化之前。功能上,BeanFactoryPostProcess对bean的处理功能更加强大。

    二.案例

       1.配置类:进行包扫描将类加载到容器中

    @ComponentScan("com.hrh.ext")
    @Configuration
    public class ExtConfig {
        @Bean
        public Person person() {
            return new Person("张三", "男");
        }
    }

      2.实体类:

    public class Person implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware {
    private String name;
    private String sex;
    
        public Person() {
            System.out.println("Person无参构造器");
    
        }
    
        public Person(String name, String sex) {
            System.out.println("Person有参构造器:[name=" + name + ",sex=" + sex + "]");
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            System.out.println("[Person]调用了BeanFactoryAware的setBeanFactory方法了:" + beanFactory);
        }
    
        @Override
        public void setBeanName(String name) {
            System.out.println("[Person]调用了BeanNameAware的setBeanName方法了:" + name);
        }
    
        @Override
        public void destroy() throws Exception {
            System.out.println("[Person]调用了DisposableBean的destroy方法了");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("[Person]调用了Initailization的afterPropertiesSet方法了");
        }
    
        @Override
        public String toString() {
            return "Person [name=" + name + ", sex=" + sex
                    + "]";
        }
    }

       3.自定义BeanFactoryPostProcessor类:

    @Component
    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            System.out.println("[MyBeanFactoryPostProcessor]调用了postProcessBeanFactory");
            int count = beanFactory.getBeanDefinitionCount();
            System.out.println("[MyBeanFactoryPostProcessor]当前beanFactory共有" + count + "个bean");
            String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
            System.out.println("[MyBeanFactoryPostProcessor]当前beanFactory有下面组件" + Arrays.asList(beanDefinitionNames));
            //获取容器中所有的beanDefinition
            for (String beanName : beanDefinitionNames) {
                if ("person".equals(beanName)) {
                    //获取PersonDefinition对象
                    BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
                    MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
                    System.out.println(propertyValues.toString());
                    //修改定义中的name属性值
                    propertyValues.addPropertyValue("name", "赵四");
                    System.out.println("[MyBeanFactoryPostProcessor]postProcessBeanFactory方法中修改了name属性初始值了");
                    System.out.println(propertyValues.toString());
                }
            }
        }
    }

      4.自定义BeanPostProcessor类:

    @Component
    public class MyBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean,
                                                      String beanName) throws BeansException {
            System.out.println("[MyBeanPostProcessor]后置处理器处理bean=【" + beanName + "】开始");
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean,
                                                     String beanName) throws BeansException {
            System.out.println("[MyBeanPostProcessor]后置处理器处理bean=【" + beanName + "】完毕!");
            return bean;
        }
    }

       5.测试:

        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ExtConfig.class);
            Person bean = context.getBean(Person.class);
            System.out.println(bean.toString());
            context.close();
        }
        
    ======运行结果======
    [MyBeanFactoryPostProcessor]调用了postProcessBeanFactory
    [MyBeanFactoryPostProcessor]当前beanFactory共有9个bean
    [MyBeanFactoryPostProcessor]当前beanFactory有下面组件[org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, extConfig, myBeanFactoryPostProcessor, myBeanPostProcessor, person]
    PropertyValues: length=0
    [MyBeanFactoryPostProcessor]postProcessBeanFactory方法中修改了name属性初始值了
    PropertyValues: length=1; bean property 'name'
    [MyBeanPostProcessor]后置处理器处理bean=【extConfig】开始
    [MyBeanPostProcessor]后置处理器处理bean=【extConfig】完毕!
    Person有参构造器:[name=张三,sex=男]
    [Person]调用了BeanNameAware的setBeanName方法了:person
    [Person]调用了BeanFactoryAware的setBeanFactory方法了:org.springframework.beans.factory.support.DefaultListableBeanFactory@e45f292: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,extConfig,myBeanFactoryPostProcessor,myBeanPostProcessor,person]; root of factory hierarchy
    [MyBeanPostProcessor]后置处理器处理bean=【person】开始
    [Person]调用了Initailization的afterPropertiesSet方法了
    [MyBeanPostProcessor]后置处理器处理bean=【person】完毕!
    Person [name=赵四, sex=null]
    [Person]调用了DisposableBean的destroy方法了

       从上面的运行结果可以看出:

        1)Person的name值由"张三"变为"赵四";

        2)BeanFactoryPostProcessor方法执行顺序先于BeanPostProcessor接口中方法,且在bean实例化之前执行;

        3)BeanFactoryPostProcessor改变bean的定义,实例化出来的对象变了:“Person有参构造器:[name=张三,sex=男] ”变成了“Person [name=赵四, sex=null]

        4)BeanPostProcessor在bean创建对象实例化后,初始化(bean执行afterPropertiesSet方法或init-method方法)前后进行拦截工作;

     三.原理

       接下来我们通过debug代码来查看BeanFactoryPostProcessor的执行流程,从AbstractApplicationContext类的构造器方法看起,这里面对应着容器初始化的基本操作;

      1.在测试main方法中下面的代码打断点:

    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ExtConfig.class);

      2.从下图可以看出容器先注册配置类ExtConfig的定义信息,然后进行refresh刷新容器;

     

      3.先来看看register(componentClasses)注册流程:从class文件读取信息解析成beanDefinition

    AnnotationConfigApplicationContextpublic void register(Class<?>... componentClasses) {
            Assert.notEmpty(componentClasses, "At least one component class must be specified");
            this.reader.register(componentClasses);
        }
    
    
    AnnotatedBeanDefinitionReader:注册beanDefinition
        public void register(Class<?>... componentClasses) {
            for (Class<?> componentClass : componentClasses) {
                registerBean(componentClass);
            }
        }
        
        public void registerBean(Class<?> beanClass) {
            doRegisterBean(beanClass, null, null, null, null);
        }
            
        //Register a bean from the given bean class, deriving its metadata from  class-declared annotations.
        //从class文件中读取bean的定义信息,并注册到容器中
        private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
            @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
            @Nullable BeanDefinitionCustomizer[] customizers) {
            //得到bean的所有定义信息:元数据metadata、作用域scope、初始化方法名字initMethodName等等
            AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
            if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
                return;
            }
            //为bean实例创建一个特殊的回调信号
            abd.setInstanceSupplier(supplier);
            //获取作用域的数据:单例
            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
            //设置bean为单例
            abd.setScope(scopeMetadata.getScopeName());
            //获取beanName
            String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
            //处理一些注释信息:lazyInit、primary、dependsOn、role、description
            AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
            if (qualifiers != null) {//qualifiers = nul 跳过
                for (Class<? extends Annotation> qualifier : qualifiers) {
                    if (Primary.class == qualifier) {
                        abd.setPrimary(true);
                    }
                    else if (Lazy.class == qualifier) {
                        abd.setLazyInit(true);
                    }
                    else {
                        abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                    }
                }
            }
            if (customizers != null) {//customizers = null跳过
                for (BeanDefinitionCustomizer customizer : customizers) {
                    customizer.customize(abd);
                }
            }
            //创建一个BeanDefinitionHolder
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
            definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            //容器中注册beanDefinition
            BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
        }

      4.refresh刷新容器:invokeBeanFactoryPostProcessors方法用来找出所有beanFactory后置处理器,并且调用这些处理器来改变bean的定义

        public void refresh() throws BeansException, IllegalStateException {
            //来个锁,不然 refresh() 还没结束,你又来个启动或销毁容器的操作,那不就乱套了嘛
            synchronized (this.startupShutdownMonitor) {
                // Prepare this context for refreshing.
                //容器刷新前的处理方法:获取启动的系统时间、设置active活跃标识、开始打印日志、设置环境变量、设置容器监听器、设置容器事件
                prepareRefresh();
    
                // Tell the subclass to refresh the internal bean factory.
                //刷新bean工厂并获取到bean工厂
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
                // Prepare the bean factory for use in this context.
                // bean工厂的初始化操作:设置类加载器、设置bean表达式解析器、设置bean后置处理器等等;
                prepareBeanFactory(beanFactory);
    
                try {
                    // Allows post-processing of the bean factory in context subclasses.
                    // 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
                    // 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】
                     // 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
                     // 具体的子类可以在这步的时候根据自身业务添加或修改一些特殊的 beanFactory属性
                    postProcessBeanFactory(beanFactory);
    
                    // Invoke factory processors registered as beans in the context.
                    //找出所有beanFactory后置处理器,并且调用这些处理器来改变bean的定义
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // Register bean processors that intercept bean creation.
    //注册bean后置处理器
    registerBeanPostProcessors(beanFactory); // Initialize message source for this context.
    //初始化容器的信息源
    initMessageSource(); // Initialize event multicaster for this context.
    //初始化事件监听多路广播器
    initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses.
    //是个空壳方法,在AnnotationApplicationContex上下文中没有实现,可能在spring后面的版本会去扩展。
    //与Web上下文有关
    onRefresh(); // Check for listener beans and register them. //注册监听器 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. //对象的创建:初始化剩下所有的(非懒加载的)单实例对象【从这里可以看出beanFactory后置处理器在初始化其他组件之前执行】 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event.
    //刷新完成工作,包括初始化LifecycleProcessor,发布刷新完成事件等
    finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources.
    //销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
    destroyBeans(); // Reset 'active' flag.
    //取消刷新的标志
    cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }

      5.打开invokeBeanFactoryPostProcessors方法,如下所示,实际操作是委托PostProcessorRegis

    trationDelegate去完成的:调用getBeanFactoryPostProcessors()方法获取手工注册到ApplicationCon

    text的容器后置处理器集合

        protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
            PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    
            // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
            // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
            if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
                beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
                beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
            }
        } 

      1)在调用PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors方法时,注意第二个入参是getBeanFactoryPostProcessors()方法,该方法返回的是applicationContext的成员变量beanFactoryPostProcessors,该成员变量的值来自AbstractApplicationContext.addBeanFactoryPostProcessor方法被调用的时候:

        private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
        @Override
        public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
            Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
            this.beanFactoryPostProcessors.add(postProcessor);
        }
    
        public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
            return this.beanFactoryPostProcessors;
        }

        2)AbstractApplicationContext.addBeanFactoryPostProcessor方法是留给业务扩展时调用的,例如在springboot初始化时,ConfigurationWarningsApplicationContextInitializer类的initialize方法中就有调用:

    @Override
    public void initialize(ConfigurableApplicationContext context) {
        context.addBeanFactoryPostProcessor(
                new ConfigurationWarningsPostProcessor(getChecks()));
    }

    6.看过了如何添加BeanFactoryPostProcessor,再回到PostProcessorRegistrationDelegate.invok

    eBeanFactoryPostProcessors方法:实例化并调用所有已注册的BeanFactoryPostProcessor bean;

    流程是:

      1)beanFactory是BeanDefinitionRegistry类型时,此条件下完成如下流程:

        1.遍历传入后置处理器集合查找类型为BeanDefinitionRegistryPostProcessor的后置处理器,调用后置处理器的postProcessBeanDefinitionRegistry方法;

        2.在容器中查找所有的实现了PriorityOrdered接口的BeanDefinition

    RegistryPostProcessor集合,对后置处理器集合排序,遍历,执行后置处理的postProcessBeanDefinitionRegistry方法;

        3.在容器中查找所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor集合,对后置处理器集合排序,遍历,执行后置处理的postProcessBeanDefinitionRegistry方法;

        4.在容器中查找其它(未实现排序接口)的BeanDefinitionRegistryPostProcessor并添加到集合nonOrderedPostProcessors中,对后置处理器集合排序,遍历,执行后置处理的postProcessBeanDefinitionRegistry方法;

        5.当前所有的BeanDefinitionRegistryPostProcessor处理器的方法postProcessBeanD

    efinitionRegistry 执行完毕后,执行其父类postProcessBeanFactory方法;

        6.执行所有非BeanDefinitionRegistryPostProcessor类型的后置处理器的postProcessB

    eanFactory方法;

        PS:BeanDefinitionRegistryPostProcessor的简介(BeanDefinitionRegistryPostProc

    essor的实现案例请查看下文第7点的后文)

         (1)我们开发的类,如果想注册到spring容器,让spring来完成实例化,常用方式如下:xml中通过bean节点来配置;使用@Service、@Controller、@Conponent等注解;
          其实,除了以上方式,spring还支持我们通过代码来将指定的类注册到spring容器中,即使用BeanDefinitionRegistryPostProcessor来进行bean的注册;

        (2)BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子类,执行顺序优先于BeanFactoryPostProcessor,执行流程跟BeanFactoryPostProcessor一样,只是会先执行postProcessBeanDefinitionRegistry再执行postProcessBeanFactory;

        (3)BeanDefinitionRegistry提供了丰富的方法来操作bean定义,判断、注册、反注册等方法都准备好了,我们在编写postProcessBeanDefinitionRegistry方法的内容时,就能直接使用入参registry的这些方法来完成判断和注册、反注册等操作;

    public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    
        //执行时机:在所有bean定义信息将要被加载,bean实例还未创建,利用下面方法给容器再额外添加一些组件
        void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
    
    }

      2)beanFactory非BeanDefinitionRegistry类型时,此条件下完成如下流程:

        1.遍历传入后置处理器集合,执行后置处理器的postProcessBeanFactory方法;

        2.在容器中(beanFactory.getBeanNamesForType)查找所有的实现了PriorityOrdered接口的BeanFactoryPostProcessor集合,对后置处理器集合排序,遍历,执行后置处理;

        3.在容器中查找所有实现了Ordered接口的BeanFactoryPostProcessor集合,对后置处理器集合排序,遍历,执行后置处理;

        4.在容器中查找其它(未实现排序接口)的BeanFactoryPostProcessor并添加到集合nonOrderedPostProcessors中,对后置处理器集合排序,遍历,执行后置处理;

        public static void invokeBeanFactoryPostProcessors(
                ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
            // Invoke BeanDefinitionRegistryPostProcessors first, if any.
            Set<String> processedBeans = new HashSet<>();
            //如果beanFactory实现了BeanDefinitionRegistry
            if (beanFactory instanceof BeanDefinitionRegistry) {
                BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
                List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    
                for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                    //如果beanFactoryPostProcessor实现了BeanDefinitionRegistryPostProcessor,分别放入两个集合:registryProcessors 和 regularPostProcessors
                    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                        BeanDefinitionRegistryPostProcessor registryProcessor =
                                (BeanDefinitionRegistryPostProcessor) postProcessor;
                        registryProcessor.postProcessBeanDefinitionRegistry(registry);
                        registryProcessors.add(registryProcessor);
                    }
                    else {
                        regularPostProcessors.add(postProcessor);
                    }
                }
    
                // Do not initialize FactoryBeans here: We need to leave all regular beans
                // uninitialized to let the bean factory post-processors apply to them!
                // Separate between BeanDefinitionRegistryPostProcessors that implement
                // PriorityOrdered, Ordered, and the rest.
                List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    
                // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
                //找出所有实现了BeanDefinitionRegistryPostProcessor接口和PriorityOrdered接口的bean,放入registryProcessors集合,
                //放入根据Set接口来排序,然后这些bean会被invokeBeanDefinitionRegistryPostProcessors方法执行;
                String[] postProcessorNames =
                        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
    
                // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
                //找出所有实现了BeanDefinitionRegistryPostProcessor接口和Ordered接口的bean,放入registryProcessors集合,
                //放入根据Set接口来排序,然后这些bean会被invokeBeanDefinitionRegistryPostProcessors方法执行;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    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);
                currentRegistryProcessors.clear();
    
                // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
                //对于那些实现了BeanDefinitionRegistryPostProcessor接口,但是没有实现PriorityOrdered和Ordered的bean也被找出来,
                //然后这些bean会被invokeBeanDefinitionRegistryPostProcessors方法执行;
                boolean reiterate = true;
                while (reiterate) {
                    reiterate = false;
                    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);
                    currentRegistryProcessors.clear();
                }
    
                // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
                //registryProcessors和regularPostProcessors集合被invokeBeanFactoryPostProcessors执行
                invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
                invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
            }
    
            else {
                // Invoke factory processors registered with the context instance.
                //入参中的BeanFactoryPostProcessor,没有实现BeanDefinitionRegistryPostProcessor的那些bean,被invokeBeanFactoryPostProcessors执行
                invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
            }
    
            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
            // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
            // Ordered, and the rest.
            //找出实现了BeanFactoryPostProcessor接口的bean,注意这里已将上面实现了BeanDefinitionRegistryPostProcessor接口的bean给剔除了,
            //将这些bean分为三类:实现了PriorityOrdered接口的放入priorityOrderedPostProcessors,
            //实现了Ordered接口的放入orderedPostProcessorNames,其他的放入nonOrderedPostProcessorNames
            //自定义的实现BeanFactoryPostProcessor接口的bean就会在nonOrderedPostProcessorNames被找出来
            List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
            List<String> orderedPostProcessorNames = new ArrayList<>();
            List<String> nonOrderedPostProcessorNames = new ArrayList<>();
            for (String ppName : postProcessorNames) {
                if (processedBeans.contains(ppName)) {
                    // skip - already processed in first phase above
                }
                else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
                }
                else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessorNames.add(ppName);
                }
                else {
                    nonOrderedPostProcessorNames.add(ppName);
                }
            }
    
            // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
            //priorityOrderedPostProcessors先排序再被invokeBeanFactoryPostProcessors执行
            sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
            // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
            //orderedPostProcessorNames先被遍历加入到orderedPostProcessors,再被排序,最后才被invokeBeanFactoryPostProcessors执行
            List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
            for (String postProcessorName : orderedPostProcessorNames) {
                orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            sortPostProcessors(orderedPostProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
            // Finally, invoke all other BeanFactoryPostProcessors.
            //nonOrderedPostProcessorNames也是先被遍历到nonOrderedPostProcessors,再被invokeBeanFactoryPostProcessors执行
            List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
            for (String postProcessorName : nonOrderedPostProcessorNames) {
                nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            //这时才是执行自定义BeanFactoryPostProcessor的postProcessBeanFactory
            invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    
            // Clear cached merged bean definitions since the post-processors might have
            // modified the original metadata, e.g. replacing placeholders in values...
            beanFactory.clearMetadataCache();
        }
      • getBeanNamesForType():根据传递的类型获取容器中的beanName
        // type:类的类型名称
        // includeNonSingletons:返回数据包含了非单例beanName
        // allowEagerInit: 可以提前加载初始化
        public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
            if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
               // 不可用缓存、类型无效、不允许提前加载初始化
               // 需要获取当前type的原始类型,继续获取数据
                return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
            }
            Map<Class<?>, String[]> cache =
                    (includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
            String[] resolvedBeanNames = cache.get(type);
            // 如果缓存已经存储了该数据,则无需再计算,直接返回即可
            if (resolvedBeanNames != null) {
                return resolvedBeanNames;
            }
            resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
            // 这一步就是真正的获取数据,遍历beanDefinitionNames的每一个数据,符合要求的就会加入到返回的列表中
            
            if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
                cache.put(type, resolvedBeanNames);
                // 便于下一次获取,加入缓存中
            }
            return resolvedBeanNames;
        }
      • getBean后面还有一个参数BeanFactoryPostProcessor.class,注意看这个函数,会发现返回的是一个抽象类,结论就是nonOrderedPostProcessors添加的不是bean实例,而是beandefinition,在实例化前。
      7.从上面代码中可以看出所有实现了BeanFactoryPostProcessor接口的bean,都被作为入参,然后调用了invokeBeanDefinitionRegistryPostProcessors或者invokeBeanFactoryPostProcessors方法去处理:对每个BeanFactoryPostProcessor接口的实现类,都调用了其接口方法,不同的是,对于实现了BeanDefinitionRegistryPostProcessor接口的bean,调用其postProcessBeanDefinitionRegistry方法的时候,入参是BeanDefinitionRegistry,而非BeanFactory,因此,实现了BeanDefinitionRegistryPostProcessor接口的bean,其postProcessBeanDefinitionRegistry在被调用时,可以通过入参BeanDefinitionRegistry来做更多和bean的定义有关的操作,例如注册bean;
        /**
         * Invoke the given BeanDefinitionRegistryPostProcessor beans.
         */
        private static void invokeBeanDefinitionRegistryPostProcessors(
                Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
    
            for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
                postProcessor.postProcessBeanDefinitionRegistry(registry);
            }
        }
            
        /**
         * Invoke the given BeanFactoryPostProcessor beans.
         */    
        private static void invokeBeanFactoryPostProcessors(
            Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
    
            for (BeanFactoryPostProcessor postProcessor : postProcessors) {
                postProcessor.postProcessBeanFactory(beanFactory);
            }
        } 
      • BeanDefinitionRegistryPostProcessor案例实现:在上面案例中多添加一个BeanDefinitionRegistryPostProcessor实现类
        @Configuration
        public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
        
        
            @Override
            public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
                System.out.println("[MyBeanDefinitionRegistryPostProcessor]postProcessBeanFactory--->bean的数量:" + beanFactory.getBeanDefinitionCount());
        
            }
        
            @Override
            public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
                System.out.println("[MyBeanDefinitionRegistryPostProcessor]postProcessBeanDefinitionRegistry--->bean的数量:" + registry.getBeanDefinitionCount());
                //给容器注册bean
                //RootBeanDefinition beanDefinition = new RootBeanDefinition(Color.class);
                AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Color.class).getBeanDefinition();
                registry.registerBeanDefinition("color",beanDefinition);
            }
        }
        =========测试执行结果=========
        [MyBeanDefinitionRegistryPostProcessor]postProcessBeanDefinitionRegistry--->bean的数量:10
        十一月 02, 2020 7:26:46 下午 org.springframework.context.annotation.ConfigurationClassPostProcessor enhanceConfigurationClasses
        信息: Cannot enhance @Configuration bean definition 'myBeanDefinitionRegistryPostProcessor' since its singleton instance has been created too early. The typical cause is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor return type: Consider declaring such methods as 'static'.
        [MyBeanDefinitionRegistryPostProcessor]postProcessBeanFactory--->bean的数量:11
        [MyBeanFactoryPostProcessor]调用了postProcessBeanFactory
        [MyBeanFactoryPostProcessor]当前beanFactory共有11个bean
        [MyBeanFactoryPostProcessor]当前beanFactory有下面组件[org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, extConfig, myBeanDefinitionRegistryPostProcessor, myBeanFactoryPostProcessor, myBeanPostProcessor, person, color]
        PropertyValues: length=0
        [MyBeanFactoryPostProcessor]postProcessBeanFactory方法中修改了name属性初始值了
        PropertyValues: length=1; bean property 'name'
        [MyBeanPostProcessor]后置处理器处理bean=【extConfig】开始
        [MyBeanPostProcessor]后置处理器处理bean=【extConfig】完毕!
        Person有参构造器:[name=张三,sex=男]
        [Person]调用了BeanNameAware的setBeanName方法了:person
        [Person]调用了BeanFactoryAware的setBeanFactory方法了:org.springframework.beans.factory.support.DefaultListableBeanFactory@e45f292: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,extConfig,myBeanDefinitionRegistryPostProcessor,myBeanFactoryPostProcessor,myBeanPostProcessor,person,color]; root of factory hierarchy
        [MyBeanPostProcessor]后置处理器处理bean=【person】开始
        [Person]调用了Initailization的afterPropertiesSet方法了
        [MyBeanPostProcessor]后置处理器处理bean=【person】完毕!
        [MyBeanPostProcessor]后置处理器处理bean=【color】开始
        [MyBeanPostProcessor]后置处理器处理bean=【color】完毕!
        Person [name=赵四, sex=null]
        [Person]调用了DisposableBean的destroy方法了

      8.BeanFactoryPostProcessor 执行的整体流程:

        1)ApplicationContext的refresh方法

        2)ApplicationContext的invokeBeanFactoryPostProcessors方法

        3)PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors

      9.BeanFactoryPostProcessor执行的优先级:

        1)首先是实现了PriorityOrdered接口的,排序执行

        2)下来是实现了Ordered接口的,排序执行

        3)最后是其它(未实现排序接口),顺序执行

      10.BeanFactoryPostProcessor获取机制:

        1)首先获取手动注册ApplicationContext的集合

        2)再次是通过beanFactory.getBeanNamesForType查找所有已注册的BeanFactory

    PostProcessor的bean定义并实例化。

    四.总结

      1. ApplicationContext扩展类可以调用AbstractApplicationContext.addBeanFactoryPostProcessor方法,将自定义的BeanFactoryPostProcessor实现类保存到ApplicationContext中;
      2. Spring容器初始化时,上一步中被加入到ApplicationContext的bean会被优先调用其postProcessBeanFactory方法;
      3. 自定义的BeanFactoryPostProcessor接口实现类,也会被找出来,然后调用其postProcessBeanFactory方法;
      4. postProcessBeanFactory方法被调用时,beanFactory会被作为参数传入,自定义类中可以使用该参数来处理bean的定义,达到业务需求;
      5. 此时的Spring容器还没有开始实例化bean,因此自定义的BeanFactoryPostProcessor实现类不要做与bean实例有关的操作,而是做一些与bean定义有关的操作,例如修改某些字段的值,这样后面实例化的bean的就会有相应的改变

       6.Spring主要将BeanFactoryPostProcessor划分了两类:

      • 正常的BeanFactoryPostProcessor
      • BeanDefinitionRegistry类型的BeanDefinitionRegistryPostProcessor

      7.在执行流程中可以看到Spring先执行了BeanDefinitionRegistryPostProcessor类型的postProcessBeanDefinitionRegistry方法,再执行BeanDefinitionRegistryPostProcessor和正常BeanFactoryPostProcessor的postProcessBeanFactory方法。

      8.Spring对BeanDefinitionRegistryPostProcessor的解释是:允许在正常的BeanFactoryPostProcessor执行检测开始之前注册更多的自定义bean。也就是说BeanDefinitionRegistryPostProcessor的方法postProcessBeanDefinitionRegistry可以在后置处理器执行前自定义注册更多的BeanDefinition

      例如:Spring实现的ConfigurationClassPostProcessor用于注册注解@Configuration标识的类里面定义的BeanDefinition。

  • 相关阅读:
    聊一聊所谓的B端C化
    NetCore3.1IIS其他网站出现HTTP503无法访问解决办法
    技术方案模板 fn
    技术方案模板
    composer的常用操作(composer 2.2.1)
    thinkphp6: 用validate验证参数合法性(thinkphp 6.0.9/php 8.0.14)
    thinkphp6: 从6.0.9升级(php 8.0.14)到 6.0.10lts版本(php 8.1.1)
    thinkphp6: 自定义配置文件(php 8.1.1 / thinkphp v6.0.10LTS)
    linux(ubuntu21.10):为chrome安装jsonvue(chrome 96)
    thinkphp6:mysql数据库使用事务(php 8.1.1 / thinkphp v6.0.10LTS)
  • 原文地址:https://www.cnblogs.com/huangrenhui/p/13903846.html
Copyright © 2011-2022 走看看