zoukankan      html  css  js  c++  java
  • 通过BeanPostProcessor理解Spring中Bean的生命周期

    通过BeanPostProcessor理解Spring中Bean的生命周期及AOP原理

    Spring源码解析(十一)Spring扩展接口InstantiationAwareBeanPostProcessor解析

    Spring bean的生命周期

    Spring作为一个优秀的框架,拥有良好的可扩展性。Spring对对象的可扩展性主要就是依靠InstantiationAwareBeanPostProcessor和BeanPostProcessor来实现的。

    • InstantiationAwareBeanPostProcessor 主要是作用于实例化阶段。
    • BeanPostProcessor 主要作用与 初始化阶段。

    注册BeanPostProcessor

    InstantiationAwareBeanPostProcessor代表了Spring的另外一段生命周期:实例化。先区别一下Spring Bean的实例化和初始化两个阶段的主要作用:

    1、实例化—-实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean放入单例池中

    2、初始化—-初始化的过程是一个赋值的过程,即调用Bean的setter,设置Bean的属性

    之前的BeanPostProcessor作用于过程(2)前后,现在的InstantiationAwareBeanPostProcessor则作用于过程(1)前后;

    InstantiationAwareBeanPostProcessor接口继承BeanPostProcessor接口,它内部提供了3个方法,再加上BeanPostProcessor接口内部的2个方法,所以实现这个接口需要实现5个方法。InstantiationAwareBeanPostProcessor接口的主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置

    public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
       this();
       register(annotatedClasses);
       refresh();
    }

    applicationContext构造方法中调用refresh()方法

    refresh() 方法中这里主要关心两个放

    • registerBeanPostProcessors(beanFactory); 注册BeanPostProcessor
    • finishBeanFactoryInitialization(beanFactory); 注册余下的Singletions Bean
    public void refresh() throws BeansException, IllegalStateException {
        // Register bean processors that intercept bean creation.
                    registerBeanPostProcessors(beanFactory);
                        // Instantiate all remaining (non-lazy-init) singletons.
                    finishBeanFactoryInitialization(beanFactory);
        }
    public static void registerBeanPostProcessors(
          ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    
       String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    
       // Register BeanPostProcessorChecker that logs an info message when
       // a bean is created during BeanPostProcessor instantiation, i.e. when
       // a bean is not eligible for getting processed by all BeanPostProcessors.
       int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
       beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    
       // Separate between BeanPostProcessors that implement PriorityOrdered,
       // Ordered, and the rest.
       List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
       List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
       List<String> orderedPostProcessorNames = new ArrayList<>();
       List<String> nonOrderedPostProcessorNames = new ArrayList<>();
       for (String ppName : postProcessorNames) {
          if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
             BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
             priorityOrderedPostProcessors.add(pp);
             if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
             }
          }
          else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
             orderedPostProcessorNames.add(ppName);
          }
          else {
             nonOrderedPostProcessorNames.add(ppName);
          }
       }
    
       // First, register the BeanPostProcessors that implement PriorityOrdered.
       sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
       registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    
       // Next, register the BeanPostProcessors that implement Ordered.
       List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
       for (String ppName : orderedPostProcessorNames) {
          BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
          orderedPostProcessors.add(pp);
          if (pp instanceof MergedBeanDefinitionPostProcessor) {
             internalPostProcessors.add(pp);
          }
       }
       sortPostProcessors(orderedPostProcessors, beanFactory);
       registerBeanPostProcessors(beanFactory, orderedPostProcessors);
    
       // Now, register all regular BeanPostProcessors.
       List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
       for (String ppName : nonOrderedPostProcessorNames) {
          BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
          nonOrderedPostProcessors.add(pp);
          if (pp instanceof MergedBeanDefinitionPostProcessor) {
             internalPostProcessors.add(pp);
          }
       }
       registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
    
       // Finally, re-register all internal BeanPostProcessors.
       sortPostProcessors(internalPostProcessors, beanFactory);
       registerBeanPostProcessors(beanFactory, internalPostProcessors);
    
       // Re-register post-processor for detecting inner beans as ApplicationListeners,
       // moving it to the end of the processor chain (for picking up proxies etc).
       beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }
    registerBeanPostProcessors

    通过beanFactory.getBeanNamesForType来获取所有BeanPostProcessor。

    BeanPostProcessor按优先级分为PriorityOrdered,Ordered和其他的,对他们分别进行操作。

    • 先beanFactory.getBean进性实例化,
    • 再使用sortPostProcessors() 进行排序,
    • 最后registerBeanPostProcessors()进行注册。

    BeanFactory.getBean()(注册Bean)

    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
         @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
    
       final String beanName = transformedBeanName(name);
       Object bean;
       //缓存
       // Eagerly check singleton cache for manually registered singletons.
       Object sharedInstance = getSingleton(beanName);
       if (sharedInstance != null && args == null) {
         bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
       }
    
       else {
         // Fail if we're already creating this bean instance:
         // We're assumably within a circular reference.
         //判断循环引用,抛异常
         if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
         }
    
         // Check if bean definition exists in this factory.
         BeanFactory parentBeanFactory = getParentBeanFactory();
         // this.beanDefinitionMap.containsKey(beanName); 就是判断有没有BeanDefinition
         if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
               return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                    nameToLookup, requiredType, args, typeCheckOnly);
            }
            else if (args != null) {
               // Delegation to parent with explicit args.
               return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else {
               // No args -> delegate to standard getBean method.
               return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
         }
    
         if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
         }
    
         try {
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);
    
            // Guarantee initialization of beans that the current bean depends on.
            // 获取bean的依赖,实例化bean前先实例化依赖。
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
               for (String dep : dependsOn) {
                  if (isDependent(beanName, dep)) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                          "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                  }
                  registerDependentBean(dep, beanName);
                  try {
                    getBean(dep);
                  }
                  catch (NoSuchBeanDefinitionException ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                          "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                  }
               }
            }
            //创建实例
            // Create bean instance.
            if (mbd.isSingleton()) {
               sharedInstance = getSingleton(beanName, () -> {
                  try {
                    return createBean(beanName, mbd, args);
                  }
                  catch (BeansException ex) {
                    // Explicitly remove instance from singleton cache: It might have been put there
                    // eagerly by the creation process, to allow for circular reference resolution.
                    // Also remove any beans that received a temporary reference to the bean.
                    destroySingleton(beanName);
                    throw ex;
                  }
               });
               bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }
    
            else if (mbd.isPrototype()) {
               // It's a prototype -> create a new instance.
               Object prototypeInstance = null;
               try {
                  beforePrototypeCreation(beanName);
                  prototypeInstance = createBean(beanName, mbd, args);
               }
               finally {
                  afterPrototypeCreation(beanName);
               }
               bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }
    
            else {
               String scopeName = mbd.getScope();
               final Scope scope = this.scopes.get(scopeName);
               if (scope == null) {
                  throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
               }
               try {
                  Object scopedInstance = scope.get(beanName, () -> {
                    beforePrototypeCreation(beanName);
                    try {
                       return createBean(beanName, mbd, args);
                    }
                    finally {
                       afterPrototypeCreation(beanName);
                    }
                  });
                  bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
               }
            }
         }
       }
    
       // Check if required type matches the type of the actual bean instance.
       if (requiredType != null && !requiredType.isInstance(bean)) {
         try {
            T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
               throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
            return convertedBean;
         }
       }
       return (T) bean;
    }
    doGetBean
    • 先getSingleton()从缓存中获取Bean,如果没有则创建。
    • 创建过程先检查有无循环依赖,有则抛出异常。
    • 实例化bean前先实例化所依赖的对象。

    createBean,调用的开端

    @Override
        protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
                Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
                if (bean != null) {
                    return bean;
                }
        //省略....
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        return beanInstance;
    
        }

    上面代码里面看到,在执行doCreateBean之前有resolveBeforeInstantiation方法;doCreateBean是创建bean的方法;
    resolveBeforeInstantiation是 判断执行InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation的接方法实现;
    下面看看执行的依据:

    执行 postProcessBeforeInstantiation方法的时机

    /**
         * Apply before-instantiation post-processors, resolving whether there is a
         * before-instantiation shortcut for the specified bean.
         * @param beanName the name of the bean
         * @param mbd the bean definition for the bean
         * @return the shortcut-determined bean instance, or {@code null} if none
         */
        protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
            Object bean = null;
            //如果beforeInstantiationResolved还没有设置或者是false(说明还没有需要在实例化前执行的操作)
            if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
                // 判断是否有注册过InstantiationAwareBeanPostProcessor类型的bean
                if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                    Class<?> targetType = determineTargetType(beanName, mbd);
                    if (targetType != null) {
                        //执行
                        bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                        if (bean != null) {
                            bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                        }
                    }
                }
                mbd.beforeInstantiationResolved = (bean != null);
            }
            return bean;
        }
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                    //只要有一个result不为null;后面的所有 后置处理器的方法就不执行了,直接返回(所以执行顺序很重要)
                    if (result != null) {
                        return result;
                    }
                }
            }
            return null;
        }
    @Override
        public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
                throws BeansException {
    
            Object result = existingBean;
            for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
                result = beanProcessor.postProcessAfterInitialization(result, beanName);
                //如果返回null;后面的所有 后置处理器的方法就不执行,直接返回(所以执行顺序很重要)
                if (result == null) {
                    return result;
                }
            }
            return result;
        }

    上面代码说明:

    如果postProcessBeforeInstantiation方法返回了Object是null;那么就直接返回,调用doCreateBean方法();
    如果postProcessBeforeInstantiation返回不为null;说明修改了bean对象;然后这个时候就立马执行postProcessAfterInitialization方法(注意这个是初始化之后的方法,也就是通过这个方法实例化了之后,直接执行初始化之后的方法;中间的实例化之后 和 初始化之前都不执行);
    在调用postProcessAfterInitialization方法时候如果返回null;那么就直接返回,调用doCreateBean方法();(初始化之后的方法返回了null,那就需要调用doCreateBean生成对象了)
    在调用postProcessAfterInitialization时返回不为null;那这个bean就直接返回给ioc容器了 初始化之后的操作 是这里面最后一个方法了;


    通过上面的描述,我们其实可以在这里生成一个代理类:原文

    postProcessAfterInstantiation调用的地方

    代码往后面执行走到了populateBean里面;这个主要是给bean填充属性的;实例化已经在 pupulateBean之前已经完成了

    //实例化bean;选择不同策略来实例化bean
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
    
    
        //省略。。。。
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                        //执行postProcessAfterInstantiation方法
                        if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                            continueWithPropertyPopulation = false;
                            break;
                        }
                    }
                }
            }
    //省略....
    
    //下面的代码是判断是否需要执行postProcessPropertyValues;改变bean的属性
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
            boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
    
            if (hasInstAwareBpps || needsDepCheck) {
                PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                if (hasInstAwareBpps) {
                    for (BeanPostProcessor bp : getBeanPostProcessors()) {
                        if (bp instanceof InstantiationAwareBeanPostProcessor) {
                            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                            pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                            if (pvs == null) {
                                return;
                            }
                        }
                    }
                }
                if (needsDepCheck) {
                    checkDependencies(beanName, mbd, filteredPds, pvs);
                }
            }
    
    //这里才是正在讲 属性值  真正的设置的我们的实例对象里面;之前postProcessPropertyValues这个还只是单纯的改变PropertyValues
    //最后还是要通过PropertyValues 设置属性到实例对象里面的
            applyPropertyValues(beanName, mbd, bw, pvs);
    
    }

    这个postProcessAfterInstantiation返回值要注意,因为它的返回值是决定要不要调用postProcessPropertyValues方法的其中一个因素(因为还有一个因素是mbd.getDependencyCheck());如果该方法返回false,并且不需要check,那么postProcessPropertyValues就会被忽略不执行;如果返回true,postProcessPropertyValues就会被执行

    postProcessPropertyValues调用的地方

    原文

    postProcessPropertyValues修改属性,但是要注意postProcessAfterInstantiation返回true;

    InstantiationAwareBeanPostProcessor总结

    1.   InstantiationAwareBeanPostProcessor接口继承BeanPostProcessor接口,它内部提供了3个方法,再加上BeanPostProcessor接口内部的2个方法,所以实现这个接口需要实现5个方法。InstantiationAwareBeanPostProcessor接口的主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置
    2.   postProcessBeforeInstantiation方法是最先执行的方法,它在目标对象实例化之前调用,该方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走
    3.   postProcessAfterInstantiation方法在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。因为它的返回值是决定要不要调用postProcessPropertyValues方法的其中一个因素(因为还有一个因素是mbd.getDependencyCheck());如果该方法返回false,并且不需要check,那么postProcessPropertyValues就会被忽略不执行;如果返回true,postProcessPropertyValues就会被执行
    4.   postProcessPropertyValues方法对属性值进行修改(这个时候属性值还未被设置,但是我们可以修改原本该设置进去的属性值)。如果postProcessAfterInstantiation方法返回false,该方法可能不会被调用。可以在该方法内对属性值进行修改
    5.   父接口BeanPostProcessor的2个方法postProcessBeforeInitialization和postProcessAfterInitialization都是在目标对象被实例化之后,并且属性也被设置之后调用的
    6.   Instantiation表示实例化,Initialization表示初始化。实例化的意思在对象还未生成,初始化的意思在对象已经生成

  • 相关阅读:
    系统架构技能之设计模式组合模式
    系统架构师基础到企业应用架构单机软件架构
    设计模式系列装饰模式
    设计模式系列命令模式
    设计模式系列外观模式
    设计模式系列原型模式
    设计模式系列代理模式
    设计模式系列桥接模式
    设计模式系列适配器模式
    设计模式系列享元模式
  • 原文地址:https://www.cnblogs.com/fanguangdexiaoyuer/p/10730990.html
Copyright © 2011-2022 走看看