Spring annotation Driven Development -- BeanFactoryPostProcessor

Posted by bodge on Mon, 02 Dec 2019 19:19:41 +0100

The post processor of BeanFactoryPostProcessor:beanFactory is called after the BeanFactory standard is initialized to customize and modify the contents of BeanFactory. All the bean definitions have been saved and loaded to beanFactory, but the instances of bean have not yet been created. BeanFactory is actually a container for spring.

public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			initMessageSource();

			// Initialize event multicaster for this context.
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			onRefresh();

			// Check for listener beans and register them.
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			finishBeanFactoryInitialization(beanFactory);//Instantiate bean

			// Last step: publish corresponding event.
			finishRefresh();
		}

		catch (BeansException ex) {
			if (logger.isWarnEnabled()) {
				logger.warn("Exception encountered during context initialization - " +
						"cancelling refresh attempt: " + ex);
			}

			// Destroy already created singletons to avoid dangling resources.
			destroyBeans();

			// Reset 'active' flag.
			cancelRefresh(ex);

			// Propagate exception to caller.
			throw ex;
		}

		finally {
			// Reset common introspection caches in Spring's core, since we
			// might not ever need metadata for singleton beans anymore...
			resetCommonCaches();
		}
	}
}

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("MyBeanFactoryPostProcessor ... postProcessBeanFactory ...");
		int count = beanFactory.getBeanDefinitionCount();
		String[] names = beanFactory.getBeanDefinitionNames();
		System.out.println("Defined:" + count + "individual bean,The name is:" + Arrays.asList(names));
	}

}

BeanPostProcessor is also a post processing phase, but the calling time of BeanPostProcessor is after the bean is created, the pre initialization method and post method are called before and after the initialization method of bean is executed.

After Java 1.8, interface methods can also have method bodies when they are defined. Interface methods with method bodies must be decorated with default, similar to the parent class:

public interface NullablIenterface {

	// @Nullable
	default void sayHello(String name) {
		System.out.println("hello" + name);
	}

	public void sayBye();
}

Principle of BeanFactoryPostProcessor:

Before the ioc container creates an object: refresh()

     2),invokeBeanFactoryPostProcessors(beanFactory);
How to find all beanfactorypostprocessors and execute their methods
Find all components of BeanFactory postprocessor directly in BeanFactory and execute their postProcessBeanFactory methods: implement BeanFactory postprocessor interface and be included in IOC container management
2) before initializing and creating other components, execute: finishBeanFactoryInitialization(beanFactory); / / initializing components

Topics: Spring Java