In depth analysis of Spring source code -- Annotation config application context

Today's pig's foot is annotationconfiguapplicationcontext. It's a long time ago to start looking at this class. It looks like a few simple codes, but there are tens of thousands of them behind it. First, the overall analysis, and then the local analysis. It's called ACAC

What is ACAC for

This class is the application context we often refer to, so to speak (personal understanding). It contains all the information of Spring application (including configuration information), and it is responsible for integrating the scattered information and functions in Spring.
When it comes to ApplicationContext, there are three ways to load the application context

  • AnnotationConfigApplicationContext
  • ClassPathXmlApplicationContext
  • FileSystemXmlApplicationContext

How does ACAC perform initialization

It has four construction methods

  • AnnotationConfigApplicationContext()
  • AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory)
  • AnnotationConfigApplicationContext(Class<?>... componentClasses)
  • AnnotationConfigApplicationContext(String... basePackages)
  1. No parameter Construction: initializes the reader and scanner. Before instantiation, the construction method of the parent class will be called to assign a value of DefaultListableBeanFactory to BeanFactory
	public AnnotationConfigApplicationContext() {
		 * Instantiate reader
		 * AnnotatedBeanDefinition  Annotated Bean
		 * Read the annotated beans
		this.reader = new AnnotatedBeanDefinitionReader(this);

		 * Instantiate a scanner
		 * Ability to scan classes, packages, and convert to bd
		 * The purpose of this scan is to scan manually. The @ ComponentScan you usually use doesn't use this scanner, but a new ClassPathBeanDefinitionScanner
		this.scanner = new ClassPathBeanDefinitionScanner(this);

    // Nonparametric construction of the parent class GenericApplicationContext
	public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
  1. Select the incoming BeanFactory by yourself
	public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {
		// Parent class method
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
  1. With one or more configuration classes
	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		//The parameterless construction method called in this indirectly calls the parameterless construction of the parent class to initialize BeanFactory
		//Initializing a reader and a scanner in your own constructor
		//Read one / more classes and register to map
  1. With package scan
	public AnnotationConfigApplicationContext(String... basePackages) {

It can be seen from this that refresh is required for every add operation of ApplicationContext (whether it is a configuration file or a common class). The following code will report the following exception if register operation is performed after the context initialization session is completed and refresh operation is not performed

AnnotationConfigApplicationContext applicationContext=
				new AnnotationConfigApplicationContext();

// Un refresh exception occurred
> Task :My-Spring:AnnotationTest.main() FAILED
Exception in thread "main" java.lang.IllegalStateException: org.springframework.context.annotation.AnnotationConfigApplicationContext@4edde6e5 has not been refreshed yet

It can be seen from this that the execution process of refresh() is the context life cycle

Life cycle of ACAC

In view of the above tests, I will treat each non empty method in refresh as a life process

	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			//The preparatory work includes setting the start time, activating the container, and obtaining the current environment verification mark that can be resolved

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

			// Prepare the bean factory for use in this context.
			//Prepare BeanFactory and put in some necessary components of BeanFactory

			try {

				// Allows post-processing of the bean factory in context subclasses.
				//There is no code in it. It needs to be expanded

				// Invoke factory processors registered as beans in the context.
				//Execute the registered factory processors in the Spring environment
				//Call the processorsbeanfactory defined by the user-defined (need to add it into the annotationconfigpplicationcontext) and the BeanFactoryPostProcessor defined by spring

				// Register bean processors that intercept bean creation.
				//Register bean processors

				// Initialize message source for this context.
				// Internationalization

				// Initialize event multicaster for this context.
				//Initialize application event broadcaster

				// Initialize other special beans in specific context subclasses.
				// Initialize some special beans

				// Check for listener beans and register them.
				// Register listener

				// Instantiate all remaining (non-lazy-init) singletons.
				// It is very important to initialize the remaining singleton objects

				// Last step: publish corresponding event.
				// Publish context refresh event
			} 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.

				// Reset 'active' flag.

				// 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...

I spent a diagram to analyze the process, as follows:

This is the life cycle of annotation config application context. In the next article, we will analyze these life processes!

115 original articles published, 76 praised, 10000 visitors+
Private letter follow

Tags: Spring Session Java

Posted on Sun, 15 Mar 2020 21:01:18 -0700 by La Parka