The next step, after processing the spring BeanFactoryPostProcessor processing is BeanPostProcessor, the refresh () method, called registerBeanPostProcessors method to deal with:

// Register bean processors that intercept bean creation. Really call is registerBeanPostProcessors getBean method (the beanFactory);Copy the code

BeanPostProcessors are handled in a similar way to BeanFactoryPostProcessor, Through the beanFactory. GetBeanNamesForType method implements the BeanPostProcessor interface of the beanFactory class, It is then dealt with in the order of PriorityOrdered, Ordered, nonOrdered. Just register functions in registerBeanPostProcessors method, the real is getBean method call.

public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {/ / find all implements the BeanPostProcessor interface class String [] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // Register BeanPostProcessorChecker that logs an info message when // a bean is created during BeanPostProcessor instantiation, When // a bean is not eligible for getting processed by all BeanPostProcessors And the reason why I want to add a plus one here is very simple, At the end of this method can add a class int BeanPostProcessorChecker beanProcessorTargetCount. = the beanFactory getBeanPostProcessorCount () + 1 + postProcessorNames.length; / / add BeanPostProcessorChecker () is mainly used to record information into the beanFactory the beanFactory. AddBeanPostProcessor (new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // Separate between BeanPostProcessors that implement PriorityOrdered, // Ordered, And the rest. / / define storage realized PriorityOrdered interface BeanPostProcessor set List < BeanPostProcessor > priorityOrderedPostProcessors = new ArrayList<>(); BeanPostProcessor List<BeanPostProcessor> internalPostProcessors = new ArrayList<>(); / / define storage has realized the Ordered set of the BeanPostProcessor interface name List < String > orderedPostProcessorNames = new ArrayList < > (); / / set of definitions for common BeanPostProcessor name a List < String > nonOrderedPostProcessorNames = new ArrayList < > (); PostProcessorNames, for (String ppName: PostProcessorNames) {// If the BeanPostProcessor instance of ppName implements the PriorityOrdered interface, Access to the corresponding BeanPostProcessor ppName instances added to priorityOrderedPostProcessors if (the beanFactory. IsTypeMatch (ppName, PriorityOrdered.class)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); / / if the corresponding also implements the BeanPostProcessor instance ppName MergedBeanDefinitionPostProcessor interface, So will ppName corresponding bean instance added to the internalPostProcessors if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); }} // If the ppName instance of BeanPostProcessor does not implement the PriorityOrdered interface, but implements the Ordered interface, Then the ppName corresponding bean instance added to the orderedPostProcessorNames else if (the beanFactory. IsTypeMatch (ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else {/ / will be added to the nonOrderedPostProcessorNames ppName nonOrderedPostProcessorNames. Add (ppName); }} // First, register the BeanPostProcessors that implement PriorityOrdered. To realize the PriorityOrdered the BeanPostProcessor interface instance sorting operation sortPostProcessors (priorityOrderedPostProcessors, the beanFactory); / / register implements PriorityOrdered the BeanPostProcessor interface instances added to the beanFactory registerBeanPostProcessors (the beanFactory, priorityOrderedPostProcessors); // Next, Register the BeanPostProcessors that implement Ordered processors. // Register the BeanPostProcessors that implement Ordered processors. orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String ppName : OrderedPostProcessorNames) {/ / according to find corresponding ppName BeanPostProcessor instance objects BeanPostProcessor pp. = the beanFactory getBean (ppName, BeanPostProcessor.class); / / will implement the Ordered the BeanPostProcessor interface added to the collection orderedPostProcessors orderedPostProcessors. Add (pp); / / if the corresponding also implements the BeanPostProcessor instance ppName MergedBeanDefinitionPostProcessor interface, So will ppName corresponding bean instance added to the internalPostProcessors if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); }} // Order postprocessors sortPostProcessors(orderedPostProcessors, beanFactory); / / register implements Ordered the BeanPostProcessor interface instances added to the beanFactory registerBeanPostProcessors (the beanFactory, orderedPostProcessors); // Now, Register all regular BeanPostProcessors. // Create a collection of BeanPostProcessors that do not implement the PriorityOrdered and Ordered interfaces List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); For (String ppName: NonOrderedPostProcessorNames) {/ / according to find corresponding ppName BeanPostProcessor instance objects BeanPostProcessor pp. = the beanFactory getBean (ppName,  BeanPostProcessor.class); / / will not achieve PriorityOrdered and Ordered the BeanPostProcessor interface added to the collection of nonOrderedPostProcessors nonOrderedPostProcessors. Add (pp); / / if the corresponding also implements the BeanPostProcessor instance ppName MergedBeanDefinitionPostProcessor interface, So will ppName corresponding bean instance added to the internalPostProcessors if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); }} / / registration does not implement PriorityOrdered and Ordered BeanPostProcessor instances added to the beanFactory registerBeanPostProcessors (the beanFactory, nonOrderedPostProcessors); // Finally, Re - register all internal BeanPostProcessors. / / all realized MergedBeanDefinitionPostProcessor type BeanPostProcessor sorting operation sortPostProcessors(internalPostProcessors, beanFactory); / / register all realized MergedBeanDefinitionPostProcessor type BeanPostProcessor into the beanFactory registerBeanPostProcessors (the 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). // Registered ApplicationListenerDetector into the beanFactory the beanFactory. AddBeanPostProcessor (new ApplicationListenerDetector(applicationContext)); }Copy the code

The BeanPostProcessor main interface has two methods:

Initialization method must carry on the processing logic @ Nullable before invoking the default Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { return bean; } after the initialization method call processing logic @ Nullable default Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException { return bean; }Copy the code

Manually add a BeanPostProcessor in registerBeanPostProcessors method, BeanPostProcessorChecker role is mainly used to record information

/ / add BeanPostProcessorChecker () is mainly used to record information into the beanFactory the beanFactory. AddBeanPostProcessor (new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));Copy the code

We can see BeanPostProcessorChecker postProcessAfterInitialization method, main is to record the log information:

/** * the after method of the post-processor, The new bean instance * @param beanName the name of the bean * @return */ @override public Object postProcessAfterInitialization(Object bean, String beanName) {// If the bean is not an instance of BeanPostProcessor && beanName is not fully used internally && beanFactory The number of beanPostProcessors currently registered is less than BeanPostProcessor Target number if (! (bean instanceof BeanPostProcessor) && ! isInfrastructureBean(beanName) && this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) { if  (logger.isInfoEnabled()) { logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() + "] is not eligible for getting processed by all BeanPostProcessors " + "(for example: not eligible for auto-proxying)"); }} // return bean; }Copy the code

There is an isInfrastructureBean method that is used to determine whether beanName is fully internal. The BeanDefinition defines the role type of the bean:

/** * Role hint that a {@code BeanDefinition} is a major part * of the application. Typically corresponds to a user-defined bean. */ int ROLE_APPLICATION = 0; /** * Some complex configuration classes ** Role hint 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; /** * Hint 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;Copy the code

Take a look at the key subinterfaces of BeanPostProcessor:

  • DestructionAwareBeanPostProcessor

postProcessBeforeDestructionCalled before the bean is destroyed, in the BeanFactory annotation, which describes the bean’s life cycle:

* <p>On shutdown of a bean factory, the following lifecycle methods apply:
* <ol>
* <li>{@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
* <li>DisposableBean's {@code destroy}
* <li>a custom destroy-method definition
Copy the code
  • MergedBeanDefinitionPostProcessor
/** * Spring uses this method to find all fields that need to be injected, * * post-process the given merged bean definition for the specified bean. * @param beanDefinition the merged bean definition for the bean * @param beanType the actual type of the managed bean instance * @param beanName the name of the  bean * @see AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors */ void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<? > beanType, String beanName);Copy the code
  • SmartInstantiationAwareBeanPostProcessor
/** * Predict the type of bean, * * Predict the type of the bean to be eventually returned from this * processor's {@link #postProcessBeforeInstantiation} callback. * <p>The default implementation returns {@code null}. * @param beanClass the raw class of the bean * @param beanName the name of the bean * @return the type of the bean, or {@code null} if not predictable * @throws org.springframework.beans.BeansException in case of errors */ @Nullable default Class<? > predictBeanType(Class<? > beanClass, String beanName) throws BeansException { return null; ** Determine the candidate constructors to use for the given bean. * <p>The default implementation returns {@code null}. * @param beanClass the raw class of the bean (never {@code null}) * @param beanName  the name of the bean * @return the candidate constructors, or {@code null} if none specified * @throws org.springframework.beans.BeansException in case of errors */ @Nullable default Constructor<? >[] determineCandidateConstructors(Class<? > beanClass, String beanName) throws BeansException { return null; } /** * solve the loop dependency problem, * * Obtain a reference for early access to the specified bean, * typically for the purpose of resolving a circular reference. * <p>This callback gives post-processors a chance to expose a wrapper * early - that is, before the target bean instance is fully initialized. * The exposed object should be equivalent to the what * {@link #postProcessBeforeInitialization} / {@link #postProcessAfterInitialization} * would expose otherwise. Note that the object returned by this method will * be used as bean reference unless the post-processor returns a different * wrapper from said post-process callbacks. In other words: Those post-process * callbacks may either eventually expose the same reference or alternatively * return the raw bean instance from those subsequent callbacks (if the wrapper * for the affected bean has been built for a call to this method already, * it will be exposes as final bean reference by default). * <p>The default implementation returns the given {@code bean}  as-is. * @param bean the raw bean instance * @param beanName the name of the bean * @return the object to expose as bean reference * (typically with the passed-in bean instance as default) * @throws org.springframework.beans.BeansException in case of errors */ default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { return bean; }Copy the code

The getEarlyBeanReference method is used to solve the problem of loop dependency.