[TOC]

Spring 7 large rear processor interface

The name of the interface instructions Interface method call timing
BeanPostProcessor You can customize the factory hooks for new bean instances Before and after initialization for each bean

See the aspect example for a classic use scenario such as AOP on beans
BeanFactoryPostProcessor You can customize the bean factoryBeanDefinitiondefine springThe refresh context method is executedrefresh()when

The delegate class is registered with a post-processor

(PostProcessorRegistrationDelegate) callback
BeanDefinitionRegistryPostProcessor You can register with the bean factoryBeanDefinition

inheritanceBeanFactoryPostProcessor
In allBeanFactoryPostProcessorMethod executed before execution

Is handled in the same delegate method, as shown belowDetailed instructions
MergedBeanDefinitionPostProcessor .
DestructionAwareBeanPostProcessor .
InstantiationAwareBeanPostProcessor .
SmartInstantiationAwareBeanPostProcessor .

BeanPostProcessor

With the BeanPostProcessor, you can intercept the creation of all beans in the container and even modify bean instances

Public interface BeanPostProcessor {/ / bean initialization method is invoked before invoking @ Nullable default Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { return bean; } / / bean after initialization method call is called @ Nullable default Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException { return bean; }}Copy the code

BeanPostProcessor sample

@Component public class BeanPostProcessorTest implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof UserService) { System.out.println("4.BeanPostProcessor. Pre-processing postProcessBeforeInitialization "); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof UserService) { System.out.println("7.BeanPostProcessor. The rear handle postProcessAfterInitialization "); } return bean; } } @Component public class UserService implements BeanFactoryAware, InitializingBean, DisposableBean { private ApplicationContext applicationContext; Public UserService() {system.out.println ("1. } @autoWired public void setApplicationContext(ApplicationContext ApplicationContext) {system.out.println ("2 ApplicationContext"); this.applicationContext = applicationContext; } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("3.Aware interface call "); } @Override public void afterPropertiesSet() throws Exception { System.out.println("6.InitializingBean.afterPropertiesSet"); } @PostConstruct public void initMethod() { System.out.println("5.init-method for @PostConstruct"); } @Override public void destroy() throws Exception { System.out.println("9.DisposableBean.destroy"); } @PreDestroy public void destroyMethod() { System.out.println("8.destroy-method for @PreDestroy"); } } @ComponentScan("com.ofwiki.postprocessor") public class Application { public static void main(String[] args) { AnnotationConfigApplicationContext application = new AnnotationConfigApplicationContext(Application.class); application.close(); }} Output the following: 1. instantiation of bean 2. dependency injection ApplicationContext of bean 3. invocation of Aware interface 4.BeanPostProcessor Pre-processing postProcessBeforeInitialization 5. The init - method for @ PostConstruct 6. InitializingBean. AfterPropertiesSet 7.BeanPostProcessor. The rear handle postProcessAfterInitialization 8. Destroy - method for @ PreDestroy 9. DisposableBean. DestroyCopy the code

BeanFactoryPostProcessor

The bean property processing container in the bean factory, in plain English, manages all the BeanDefinition data in our bean factory, and can modify the properties as we wish.

@Component public class BeanFactoryPostProcessorTest implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService"); System.out.println("bean class name:"+beanDefinition.getBeanClassName()); System. The out. Println (" in current the BeanFactory have "+ the BeanFactory. GetBeanDefinitionCount () +" Bean "); System.out.println("bean names:" + Arrays.asList(beanFactory.getBeanDefinitionNames())); }}Copy the code

The callback time to spring BeanFactoryPostProcessor and BeanDefinitionRegistryPostProcessor

Spring after the initial create bean factory, will be called org. Springframework. Context. Support. AbstractApplicationContext# refresh to refresh the Spring context, After the beanFactory ready and will perform invokeBeanFactoryPostProcessors (the beanFactory) method

  • invokeBeanFactoryPostProcessors(beanFactory)The method calls both post-handlers, via the delegate classBeanFactoryPostProcessor.BeanDefinitionRegistryPostProcessorThe method of
  • Factory will be in the two rear processor bean and manually add post processor (enclosing beanFactoryPostProcessors) combined with calls
  • The two postprocessors are inherited and execute all subinterfaces firstBeanDefinitionRegistryPostProcessorInstance method, and then tune all parent interfacesBeanFactoryPostProcessorMethod of instance

You can manually add a rear processor using the following method

public class ApplicationTest {
    public static void main(String[] args) {
        AbstractApplicationContext context = new AnnotationConfigApplicationContext();
        context.addBeanFactoryPostProcessor(newMyBeanFactoryPostProcessor()); context.refresh(); }}Copy the code

Detailed execution order

  1. performBeanDefinitionRegistryPostProcessorThe method of
    • 1.1 Manually AddedBeanDefinitionRegistryPostProcessorBy {@ link AbstractApplicationContext# addBeanFactoryPostProcessor} method is added to a {@ the link Bean AbstractApplicationContext# beanFactoryPostProcessors}
    • 1.2 beanFactory implementationPriorityOrderedOf the interfaceBeanDefinitionRegistryPostProcessor. Such asConfigurationClassPostProcessor
    • 1.3 beanFactory implementationOrderedOf the interfaceBeanDefinitionRegistryPostProcessor
    • 1.4 Loop through the beanFactory to find other unexecuted objects that do not need sortingBeanDefinitionRegistryPostProcessorAnd execute, including three not the following three:
      • PriorityOrdered.
      • Orderedthe
      • And in theBeanDefinitionRegistryPostProcessorMethod is dynamically registered to the beanFactory when called backBeanDefinitionRegistryPostProcessor
  2. performBeanFactoryPostProcessorThe method of
    • 2.1 Performing All OperationsBeanDefinitionRegistryPostProcessorThe type ofBeanFactoryPostProcessormethods

      In front ofBeanDefinitionRegistryPostProcessorAre stored in one until the callback is executedList<BeanFactoryPostProcessor>In the collection

      Loop through the collection, and the callback executesBeanFactoryPostProcessorSo hereBeanFactoryPostProcessorThe order of execution is previousBeanDefinitionRegistryPostProcessorThe same
    • 2.2 Manually addedBeanFactoryPostProcessorBy {@ link AbstractApplicationContext# addBeanFactoryPostProcessor} method is added to a {@ the link Bean AbstractApplicationContext# beanFactoryPostProcessors}
    • Implemented in 2.3 beanFactoryPriorityOrderedOf the interfaceBeanFactoryPostProcessor
    • 2.4 beanFactory implementationOrderedOf the interfaceBeanFactoryPostProcessor
    • 2.5 Other items in beanFactory that do not need sortingBeanFactoryPostProcessor

Delegate class source code analysis

final class PostProcessorRegistrationDelegate {
    // omit other methods....
    
   / * * *@param beanFactory
     * @paramBeanFactoryPostProcessors manually call AbstractApplicationContext# addBeanFactoryPostProcessor add post processor * /
    public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List
       
         beanFactoryPostProcessors)
        {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
        / / save has been called a ` BeanDefinitionRegistryPostProcessor ` beanName, used for marking, avoid repeated calls
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			// Save the manually added BeanFactoryPostProcessor
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			/ / spring BeanFactoryPostProcessor BeanDefinitionRegistryPostProcessor inheritance, saved the follow-up can traverse a collection spring BeanFactoryPostProcessor callback method directly
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
                    / / 1.1. Execute manually add ` BeanDefinitionRegistryPostProcessor `
                    / / by ` AbstractApplicationContext# addBeanFactoryPostProcessor ` method added to the ` AbstractApplicationContext# beanFactoryPostProcessors ` bean
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					// Add to the collection, the subsequent callback to BeanFactoryPostProcessor's method
					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.
            / / save BeanDefinitionRegistryPostProcessor specified type
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            / / start - 1.2. The callback implements in the beanFactory ` PriorityOrdered ` interface ` BeanDefinitionRegistryPostProcessor `
            String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true.false);
			for (String ppName : postProcessorNames) {
			    / / search implementation from the beanFactory PriorityOrdered BeanDefinitionRegistryPostProcessor interface
				if(beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); }}/ / sorting
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			/ / will be realized PriorityOrdered interface BeanDefinitionRegistryPostProcessor merged into collection, subsequent spring BeanFactoryPostProcessor callback methods
			registryProcessors.addAll(currentRegistryProcessors);
            / / callback BeanDefinitionRegistryPostProcessor method
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			// Clear the information set for later use
			currentRegistryProcessors.clear();
			/ / end - 1.2. The callback implements in the beanFactory ` PriorityOrdered ` interface ` BeanDefinitionRegistryPostProcessor `


			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            / / start - 1.3. The callback implements in the beanFactory ` Ordered ` interface ` BeanDefinitionRegistryPostProcessor `
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true.false);
			for (String ppName : postProcessorNames) {
                / / find realized Ordered from the beanFactory interface and untreated BeanDefinitionRegistryPostProcessor callback
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
            / / sorting
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			/ / will realize the Ordered interface BeanDefinitionRegistryPostProcessor merged into collection, subsequent spring BeanFactoryPostProcessor callback methods
			registryProcessors.addAll(currentRegistryProcessors);
			/ / callback BeanDefinitionRegistryPostProcessor method
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // Clear the information set for later use
			currentRegistryProcessors.clear();
            / / end - 1.3. The callback implements in the beanFactory ` Ordered ` interface ` BeanDefinitionRegistryPostProcessor `


			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            / / start - 1.4. Loop through the beanFactory in other don't need to sort the unimplemented ` BeanDefinitionRegistryPostProcessor ` and executed
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true.false);
				for (String ppName : postProcessorNames) {
				    / / to find other BeanDefinitionRegistryPostProcessor untreated callback
					if(! processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName);/ / BeanDefinitionRegistryPostProcessor method may add other BeanDefinitionRegistryPostProcessor the beanFactory, so need to cycle again
						reiterate = true; }}/ / sorting
				sortPostProcessors(currentRegistryProcessors, beanFactory);
                // merge into the collection, then call back to BeanFactoryPostProcessor's methods
				registryProcessors.addAll(currentRegistryProcessors);
				/ / callback BeanDefinitionRegistryPostProcessor method
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}
            / / end - 1.4. Loop through the beanFactory in other don't need to sort the unimplemented ` BeanDefinitionRegistryPostProcessor ` and executed

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            / / 2.1 callback all ` BeanDefinitionRegistryPostProcessor ` types of ` spring BeanFactoryPostProcessor ` method
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			// 2.2 Callback the manually added 'BeanFactoryPostProcessor' method
            // Through AbstractApplicationContext# addBeanFactoryPostProcessor method added to the AbstractApplicationContext# beanFactoryPostProcessors bean
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			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!
        // Get the beanName of all beanFactoryPostProcessors in beanFactory
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true.false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
        // All implement the PriorityOrdered interface BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		// All Beannames that implement the Ordered interface BeanFactoryPostProcessor
		List<String> orderedPostProcessorNames = new ArrayList<>();
		// Other BeanFactoryPostProcessor beanName that does not need sorting
		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.
		// 2.3 beanFactory implements' PriorityOrdered 'BeanFactoryPostProcessor,
        // sort, callback
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        // 2.4 beanFactory implements' Ordered 'interface' BeanFactoryPostProcessor '
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		// sort, callback
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);


		// Finally, invoke all other BeanFactoryPostProcessors.
        // Other 'beanFactory PostProcessor' in 2.5 beanFactory
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		// Do not need to sort, direct callback
		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(); }}Copy the code