spring源码之BeanPostProcessor

 

前言

spring的强大点之一,在于它给我们提供了许多的扩展点,其中非常重要的一个接口就是BeanPostProcessor。

概述

我们可以IOC的依赖注入阶段分为三个阶段,即实例化,属性注入、初始化。在分析之前,先来熟悉下几个接口BeanPostProcessor、InstantiationAwareBeanPostProcessor、SmartInstantiationAwareBeanPostProcess、MergedBeanDefinitionPostProcessor接口。这几个接口是我们本篇要分析的。

BeanPostProcessor是最上层的接口,Factory hook that allows for custom modification of new bean instances,就是说在整个依赖注入阶段,用户可以自定义修改。它提供给两个方法,在依赖注入的初始化方法调用前后调用。

InstantiationAwareBeanPostProcessor继承自BeanPostProcessor,除了父接口的方法后,还添加了方法,分别在实例化前、实例化后、属性注入后。

SmartInstantiationAwareBeanPostProcessor继承自InstantiationAwareBeanPostProcessor,增加了三个方法,分别用来预测最终的返回类型、获取构造器数组、解析循环引用

源码分析

在分析BeanPostProcessor如何工作之前,我们首先把BeanPostProcessor注册到容器当中去

  • 注册过程,代码挺长,但整个过程比较简单。
    • 将实现了BeanPostProcessor接口的bean注册到AbstractBeanFactory的beanPostProcessors链表,其中beanPostProcessors的排序按实现了PriorityOrdered、Ordered、没有实现上述接口的、实现了MergedBeanDefinitionPostProcessor接口的进行排序。
    • 如果当中有实现了InstantiationAwareBeanPostProcessor接口的,则设置hasInstantiationAwareBeanPostProcessors为true
    • 如果当中有实现了DestructionAwareBeanPostProcessor的,则设置hasDestructionAwareBeanPostProcessors为true。其中beanPostProcessors的排序按实现了PriorityOrdered、Ordered、没有实现上述接口的进行排序。
//AbstractApplicationContext类的方法
//注册BeanPostProcessor
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
//PostProcessorRegistrationDelegate类的方法
//注册BeanPostProcessor到AbstractBeanFactory的beanPostProcessors属性中
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<BeanPostProcessor>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    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(beanFactory, priorityOrderedPostProcessors);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // Next, register the BeanPostProcessors that implement Ordered.
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    sortPostProcessors(beanFactory, orderedPostProcessors);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // Now, register all regular BeanPostProcessors.
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    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(beanFactory, internalPostProcessors);
    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));
}

上面已经把所有的BeanPostProcessor注册到链表上了。下面来看下在依赖注入过程中这些BeanPostProcessor如何起作用的。整个开始入口在AbstractAutowireCapableBeanFactory的createBean方法。

  • 创建bean的入口,这里我们可以看到BeanPostProcessor的使用无处不在
    • 实例化前
    • 实例化时
    • 实例化后合并bean定义
    • 循环依赖时
    • 注入时
    • 初始化时
    • 最后注册DestructionAwareBeanPostProcessor的适配器
//AbstractAutowireCapableBeanFactory类的方法
protected
Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { //如果有后置处理,那么返回proxy Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } //这里是真正的创建Bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }  
//AbstractAutowireCapableBeanFactory类的方法
//创建bean的入口
protected
Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); mbd.resolvedTargetType = beanType; // Allow post-processors to modify the merged bean definition. //让后置处理器来修改BeanDefinition synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { exposedObject = initializeBean(beanName, exposedObject, mbd); } } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } //循环引用时的处理 if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
  • bean实例前

总结

本篇主要是对初始化过程和请求处理的入口进行分析。我们看到上面的初始化过程主要做了两件事情

  • 创建了一个IOC容器
  • 把HandlerMapping、HandlerAdapter等属性设置进来

其实这个过程并不是这么简单的,目前我们只是分析了web.xml内容解析,并没有对dispatcher-servlet.xml的解析过程进行分析。后面会结合dispatcher-servlet.xml的解析过程和请求过程来分析,这样会对整个过程更为清楚。

后面的博文会对下面几块进行分析

  • 通过请求怎么找到controller对应的方法
  • 请求参数和方法参数怎么绑定起来
  • 拦截器链怎么生成
  • 异常怎么处理
  • @ResponseBody注解的流程
  • 视图解析器的处理流程

参考链接

  • https://www.cnblogs.com/weknow619/p/6341395.html(ContextLoaderListener与DispatcherServlet的创建的上下文)
  • http://www.cnblogs.com/fangjian0423/p/springMVC-dispatcherServlet.html(源码分析参考博文)
  • https://blog.csdn.net/qq_21033663/article/details/52374436(解析器参考博文)

猜你喜欢

转载自www.cnblogs.com/lucas2/p/9430169.html