前言
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(解析器参考博文)
原文地址:https://www.cnblogs.com/lucas2/p/9430169.html