Detailed explanation of the startup process of Spring source code

catalogue

1. Initialization of container

(1) Some things that construction methods do

(2) register() registers the configuration class

2. refresh() 

      Earlier, we summarized and combed the Bean life cycle in order to have a deeper understanding of the Spring container startup and Bean instantiation process. You can go in and have a look at those you haven't seen (article link: Spring source code: Bean's life cycle running snail kieasr CSDN blog )It is also helpful to understand the content of this article. This section will enter the Spring container startup process in more detail and comprehensively, and directly hit the underlying logic of Bean instantiation. In order to facilitate everyone to read, due to the large content, it is divided into several chapters. Next, we will enter the first chapter - container startup:

1. Initialization of container

         We regard Spring as a container for producing beans, which contains N multiple Bean objects.

         ApplicationContext is an important interface of Spring context. It has two important implementation classes:

  • AnnotationConfigApplicationContext
  • ClassPathXmlApplicationContext

        Let's take AnnotationConfigApplicationContext as an example. First, let's take a look at its parent class GenericApplicationContext:

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {

	private final DefaultListableBeanFactory beanFactory;

	/**
	 * Create a new GenericApplicationContext.
	 * @see #registerBeanDefinition
	 * @see #refresh
	 */
	public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}

         See its construction method:

	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		// this() will first call the parameterless construction method of the parent class GenericApplicationContext and construct a BeanFactory - DefaultListableBeanFactory
		this();
		register(componentClasses);
		refresh();
	}

(1) Some things that construction methods do

        Before calling the constructor of AnnotationConfigApplicationContext,   In this() method, the parameterless construction method of the parent class GenericApplicationContext will be called to construct a BeanFactory - DefaultListableBeanFactory. DefaultListableBeanFactory is the ancestor of the container. Take a look at its inheritance relationship first:

         As you can see, DefaultListableBeanFactory is an integrator. In Spring, different interfaces are specified for different operations of beans, and each interface has its own corresponding implementation. Finally, all implementations are gathered together in DefaultListableBeanFactory.

         Let me briefly introduce the functions of each class:

  1. BeanFactory: this interface is known by its name as a Bean factory, which is the top-level interface of the Spring container. The BeanFactory interface defines various methods for obtaining beans, judging whether beans exist, judging whether beans are singletons, and other basic methods for beans;

  2. ListableBeanFactory: this interface inherits from BeanFactory. On the basis of BeanFactory, it extends the query method of Bean, such as obtaining BeanNames according to type, obtaining BeanNames according to annotation, obtaining annotation according to Bean, etc;

  3. AutowireCapableBeanFactory: this interface inherits from BeanFactory and provides operations such as Bean creation, configuration, injection and destruction on the basis of BeanFactory. Sometimes when we need to inject beans manually, we can consider implementing this interface. An important application of AutowireCapableBeanFactory in Spring Security is ObjectPostProcessor.

  4. Hierarchical BeanFactory: this interface inherits from BeanFactory and adds a method to obtain parent beanfactory on the basis of BeanFactory;

  5. SingletonBeanRegistry: this interface defines the definition of a singleton Bean and its acquisition method;

  6. ConfigurableBeanFactory: this interface mainly defines various configurations and destruction methods for BeanFactory;

  7. ConfigurableListableBeanFactory: This is the configuration list of BeanFactory, where the ignored types and interfaces are defined. Obtain BeanDefinition and freeze BeanDefinition through the name of the Bean;

  8. Alias registry: this interface defines the registration, removal, judgment and query operations of alias;

  9. Simpleliasregistry: this class implements the alias registry interface and its methods. Simpleliasregistry uses ConcurrentHashMap as the carrier to register, remove, judge and query alias;

  10. DefaultSingletonBeanRegistry: this class implements the SingletonBeanRegistry interface based on the collection in Java;

  11. FactoryBeanRegistrySupport: this class inherits from DefaultSingletonBeanRegistry, and adds operations such as obtaining FactoryBean type and removing FactoryBean cache on the basis of DefaultSingletonBeanRegistry;

  12. AbstractBeanFactory: implements the ConfigurableBeanFactory interface, inherits from FactoryBeanRegistrySupport, and implements the methods defined in ConfigurableBeanFactory in AbstractBeanFactory;

  13. AbstractAutowireCapableBeanFactory: this class inherits from AbstractBeanFactory and implements the methods defined in the AutowireCapableBeanFactory interface;

  14. BeanDefinitionRegistry: this interface inherits from the alias registry interface and adds a series of methods for registering, removing, querying and judging BeanDefinition;

  15. The final DefaultListableBeanFactory naturally has all the above functions.

        OK, let's go back to the construction method of the AnnotationConfigApplicationContext container. Here, we will initialize two core components first:

	public AnnotationConfigApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

        a. AnnotatedBeanDefinitionReader is a BeanDefinition reader

	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		this.registry = registry;
		// Create a parser with @ Conditional annotation
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
		// Register beandefinition*****
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

         Enter the registerAnnotationConfigProcessors() method. Spring will register many components in the container when constructing AnnotatedBeanDefinitionReader. The parameter registry passed in here is DefaultListableBeanFactory:

         Class: org.springframework.context.annotation.AnnotationConfigUtils

	public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			// Set the OrderComparator of beanFactory to annotationawarerder comparator
			// It is a Comparator for sorting, such as new ArrayList < > (). Sort (Comparator)
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			// The contextannotationautowirecandideresolver class is an annotation candidate parser (mainly dealing with @ Lazy), which is used to infer whether a Bean needs dependency injection
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

		// Register BeanDefinition of ConfigurationClassPostProcessor type
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Register the BeanDefinition of the AutowiredAnnotationBeanPostProcessor type
		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		// Register BeanDefinition of CommonAnnotationBeanPostProcessor type
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
		// Register BeanDefinition of PersistenceAnnotationBeanPostProcessor type
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Register the BeanDefinition of EventListener methodprocessor type to process the @ EventListener annotation
		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		// Register the BeanDefinition of defaulteventlistener factory type to handle the @ EventListener annotation
		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}

          The annotationawarerecomparator class is a comparator, which will be used for sorting later.         

         The contextannotationautowirecandideresolver class is an annotation candidate parser (mainly dealing with @ Lazy annotations). Its topmost parent class simpleautowirecandideresolver is used to resolve the isAutowireCandidate attribute of BeanDefinition, which will be used later in dependency injection.

        Therefore, these two classes will be set when the container is initialized.

        b.ClassPathBeanDefinitionScanner is a scanner. It is mainly used to scan and register BeanDefinition, scan a package path, and analyze the scanned classes, such as:

​
    @Test
    public void testClassPathBeanDefinitionScanner() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.refresh();
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(applicationContext);
        scanner.scan("cn.kieasar");
        System.out.println(applicationContext.getBean("goodsService"));
    }

         Set at the same time:
                 i.   Set this.includeFilters  =  AnnotationTypeFilter(Component.class)
                 ii.   Setting environment
                 iii.   Setting up resourceLoader

	public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
			Environment environment, @Nullable ResourceLoader resourceLoader) {

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		this.registry = registry;

		if (useDefaultFilters) {
			// Register the default annotation filter and scan @ Component annotations by default
			registerDefaultFilters();
		}
		setEnvironment(environment);
		setResourceLoader(resourceLoader);
	}

          Enter the registerDefaultFilters() method:

         Class: org.springframework.context.annotation.classpathscanningandidatecomponentprovider

	protected void registerDefaultFilters() {
		// Register the annotation typefilter corresponding to @ Component, and scan @ Component annotations by default
		this.includeFilters.add(new AnnotationTypeFilter(Component.class));
		ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
		try {
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
			logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
			// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
		}
		try {
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
			logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - simply skip.
		}
	}

(2) register() registers the configuration class

      Next, the register() method in the constructor of AnnotationConfigApplicationContext encapsulates the passed configuration class into BeanDefinition, and then registers it in the Spring container.

	public void register(Class<?>... componentClasses) {
		Assert.notEmpty(componentClasses, "At least one component class must be specified");
		this.reader.register(componentClasses);
	}
	public void register(Class<?>... componentClasses) {
		for (Class<?> componentClass : componentClasses) {
			registerBean(componentClass);
		}
	}

          Eventually, it will call the doRegisterBean() method:

         Class: org.springframework.context.annotation.AnnotatedBeanDefinitionReader

	private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
			@Nullable BeanDefinitionCustomizer[] customizers) {

		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}

		abd.setInstanceSupplier(supplier);
		// The result of parsing @ Scope annotation is ScopeMetadata
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		abd.setScope(scopeMetadata.getScopeName());
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		if (qualifiers != null) {
			for (Class<? extends Annotation> qualifier : qualifiers) {
				if (Primary.class == qualifier) {
					abd.setPrimary(true);
				}
				else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);
				}
				else {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		if (customizers != null) {
			for (BeanDefinitionCustomizer customizer : customizers) {
				customizer.customize(abd);
			}
		}

		// Wrap BeanDefinition as BeanDefinitionHolder
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		// Register BeanDefinition in Spring
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

         Enter the registerBeanDefinition() method:  

         Class: org.springframework.beans.factory.support.BeanDefinitionReaderUtils

	public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();
		// Register BeanDefinition in beanDefinitionMap
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// Register aliases for bean name, if any.
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

2. refresh() 

        After the initialization of the container, the next step is to execute the refresh() method. refresh() is the core method and the most important one in the Spring container startup process. It must be executed for Spring container startup and Bean instantiation. This method includes:

/**
	 * This method is the core method of spring container initialization. It is the core process of spring container initialization and the application of a typical parent class template design pattern
	 *    According to different context objects, they will be transferred to different subclass methods of context objects
	 * The core context subclasses are:
	 * ClassPathXmlApplicationContext
	 * FileSystemXmlApplicationContext
	 * AnnotationConfigApplicationContext
	 * EmbeddedWebApplicationContext(springboot).
	 */
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			/**
			 *  Importance: 5
			 *  1,Create BeanFactory object
			 *  2,xml analysis
			 *     Traditional tag parsing: bean, import, etc
			 *     Custom label resolution, such as: < context: component scan base package = "com. XXX. XXX" / >
			 *     Custom label resolution process:
			 *        a,Find the corresponding namespaceUri according to the header information of the current parsing tag
			 *        b,Load the spring.handlers file in all spring jar s. And establish mapping relationship
			 *        c,Find the corresponding class that implements the NamespaceHandler interface from the mapping relationship according to the namespaceUri
			 *        d,Call the init method of the class. The init method is a parsing class that registers various custom tags
			 *        e,Find the corresponding parsing class based on namespaceUri, and then invoke the paser method to complete the label parsing.
			 *  3,Encapsulate the parsed xml tag into a BeanDefinition object
			 */
			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			/**
			 * Prepare BeanFactory
			 * 1.Set the class loader, SpringEL expression parser and type conversion Registrar of BeanFactory
			 * 2.Add three beanpostprocessors (which are specific BeanPostProcessor instance objects)
			 * 3.Record ignoreDependencyInterface
			 * 4.Record resolvable dependency
			 * 5.Add three singleton beans
			 */
			prepareBeanFactory(beanFactory);

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

				/**
				 * (Scan scanner.scan())
				 * BeanFactory When ready, execute BeanFactory postprocessor to process BeanFactory
				 * At this time, there are 6 beandefinitions in beanMap of BeanFactory (5 basic beandefinitions + beandefinitions of AppConfig)
				 * Among the six, there is only one beanfactoryprocessor: ConfigurationClassPostProcessor
				 * Here, the ConfigurationClassPostProcessor will scan @ Component, and the scanned BeanDefinition will be registered in BeanFactory
				 * Other beanfactoryprocessors may also be scanned and executed in this step after scanning
				 * Call these interfaces: BeanDefinitionRegistryPostProcessor, beanfactoryprocessor, ConfigurationClassPostProcessor
				 */
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				// Instantiate and sort the classes that implement the beanpostprocessor interface, and add them to the beanpostprocessor property of BeanFactory
				registerBeanPostProcessors(beanFactory);

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

				// Initialize event multicaster for this context.
				// Initialize the event publisher and create a simpleapplicationeventmulticast class in the singleton pool
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// This method focuses on understanding the template design pattern. In spring boot, this method is used for embedded tomcat startup
				onRefresh();

				// Check for listener beans and register them.
				// Register the event listener in the event publisher. The core logic of event publishing is here
				registerListeners();

				/**
				 * This method is one of the most important methods in spring
				 *  Therefore, this method must be understood and seen in detail
				 *  1,Bean Instantiation process
				 *  2,IOC
				 *  3,Annotation support
				 *  4,BeanPostProcesApplicationListenersor Implementation of
				 *  5,AOP Entrance to
				 */
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				// The operation when the Spring container is closed, notifies the lifecycle processor of the refresh process, and issues a ContextRefreshEvent notification at the same time
				finishRefresh();
			}
  1. prepareRefresh():
             i.   Record the start-up time;
             ii.   You can allow sub containers to set some content into the Environment
             iii.   Verify that the Environment includes the required attributes
  2. obtainFreshBeanFactory(): its main function is to create a BeanFactory DefaultListableBeanFactory to refresh the BeanFactory. Here, it will call the refreshBeanFactory method of the subclass. The specific subclass refresh depends on the subclass, and then call the getBeanFactory method of the subclass to get a BeanFactory again;
  3.  prepareBeanFactory(beanFactory):
  4. i.   Set the class loader of beanFactory;
    ii.   Set the expression parser: StandardBeanExpressionResolver, which is used to parse expressions in Spring
    iii.   Add PropertyEditorRegistrar: ResourceEditorRegistrar, PropertyEditor type converter registrar, which is used to register some default propertyeditors;
    iv.   Add a Bean post processor: ApplicationContextAwareProcessor, which is a BeanPostProcessor used to execute callback methods such as EnvironmentAware and ApplicationEventPublisherAware;
    v.   Add ignoredDependencyInterface: you can add some interfaces to this attribute. If a class implements this interface and some set methods in this class also exist in the interface, this set method will not be executed during automatic injection, such as the interface EnvironmentAware. If a class implements this interface, Then you must implement its setEnvironment method, which is a set method and conflicts with autowire in spring. Spring will not call setEnvironment method during automatic injection, but wait until the callback Aware receives it
    Call again when you speak (note that this function is limited to the autowire of xml, and the @ Autowired annotation ignores this attribute);
        a. EnvironmentAware
        b. EmbeddedValueResolverAware
        c. ResourceLoaderAware
        d. ApplicationEventPublisherAware
        e. MessageSourceAware
        f. ApplicationContextAware
        g.   In addition, in fact, when constructing BeanFactory, another three have been added in advance:
        h. BeanNameAware
        i. BeanClassLoaderAware
        j. BeanFactoryAware.
    vi.   Add resolvableDependencies: when performing dependency injection by byType, the Bean will be found according to the type from this attribute:
        a.   BeanFactory.class: current BeanFactory object
        b.   ResourceLoader.class: current ApplicationContext object
        c.   ApplicationEventPublisher.class: current ApplicationContext object
        d.   ApplicationContext.class: current ApplicationContext object
    vii.   Add a post processor of a Bean: ApplicationListenerDetector, which is a BeanPostProcessor to judge whether a Bean is an applicationlister. If so, add the Bean to the ApplicationContext. Note that an applicationlister can only be a single instance;
    viii.   Add a post processor of a Bean: loadTimeWeaver wareprocessor, which is a BeanPostProcessor to judge whether a Bean implements the loadTimeWeaver interface. If so, set the loadTimeWeaver callback setLoadTimeWeaver method in ApplicationContext to the Bean.
    ix.   Add some singleton bean s to the singleton pool:
        a.   "Environment": environment object;
        b.   "systemProperties": Map object returned by System.getProperties();
        c.   "systemEnvironment": Map object returned by System.getenv();
  5. postProcessBeanFactory(beanFactory)  :   Subclasses provided to AbstractApplicationContext can be extended. For specific subclasses, you can continue to add some more things to BeanFactory
  6.   Invokebeanfactoryprocessors (beanfactory): executes beanfactoryprocessor
    i.   At this time, there will be a BeanFactory postprocessor in BeanFactory: ConfigurationClassPostProcessor, which is also a
    BeanDefinitionRegistryPostProcessor
    iii.   Find the beanName of type BeanDefinitionRegistryPostProcessor from beanfactory, that is, ConfigurationClassPostProcessor,   Then call the getBean method of BeanFactory to get the instance object.
    iv.   Execute the * * postProcessBeanDefinitionRegistry() * * method of * * ConfigurationClassPostProcessor:
        a.   Resolve AppConfig class
        b.   Scan the BeanDefinition and register it
        c.   Parse @ Import, @ Bean and other annotations to get the BeanDefinition and register
        d.   Look at the other notes in detail and specifically analyze how the configuration class postprocessor works
        e.   Here, we only need to know that beandefinitions will be obtained in this step, and beanfactoryprocessor and BeanDefinitionRegistryPostProcessor may exist in these beandefinitions. Therefore, after executing the postProcessBeanDefinitionRegistry() method of ConfigurationClassPostProcessor, we need to continue to execute the functions of other beandefinitionregistrypostprocessors
    postProcessBeanDefinitionRegistry() method
    v.   Execute the postProcessBeanDefinitionRegistry() method of other beandefinitionregistrypostprocessors
    vi.   Execute the * * postProcessBeanFactory() method of all beandefinitionregistrypostprocessors
    vii.   Phase II
    viii.   Find the beanName of type beanfactoryprocessor from BeanFactory, and these beanfactoryprocessors include the BeanDefinitionRegistryPostProcessor above
    ix.   Execute the postProcessBeanFactory() method of beanfactoryprocessor that has not been executed
  7. So far, all the logic of beanfactoryprocessor has been executed. The main thing to do is to get the BeanDefinition and register it in BeanFactory
  8.   Register beanPostProcessors (BeanFactory): because the above steps have completed the scanning, the programmer may define some beanPostProcessors himself. In this step, all beanPostProcessors in BeanFactory will be found, instantiated, an object will be obtained, and added to BeanFactory (attribute beanPostProcessors), Finally, add an ApplicationListenerDetector object again (it has been added before. This is to move the ApplicationListenerDetector to the end)
  9. initMessageSource(): if there is a BeanDefinition called "messageSource" in BeanFactory, the Bean object will be created and assigned to the messageSource property of ApplicationContext, so that ApplicationContext has the function of internationalization
  10. Initapplicationeventmulticast(): if there is a BeanDefinition called "applicationeventmulticast" in BeanFactory, the Bean object will be created and assigned to the applicationeventmulticast property of ApplicationContext, so that ApplicationContext can have the function of event publishing
  11. onRefresh(): extend the subclass provided to AbstractApplicationContext, Springboot
  12.   registerListeners(): obtain the beanName of ApplicationListener type from BeanFactory, and then add it to the event broadcaster applicationeventmulticast in ApplicationContext. In this step, because the FactoryBean has not called the getObject() method to generate the Bean object, you should find the ApplicationListener according to the type and record the corresponding beanName
  13. finishBeanFactoryInitialization(beanFactory): to complete the initialization of BeanFactory, it is mainly to instantiate a non lazy loaded singleton Bean, which will be described in a separate note.
  14. finishRefresh(): after the initialization of BeanFactory, it is the last step of Spring startup
  15. Set the lifecycle processor of ApplicationContext. Defaultlifecycle processor is set by default
  16. Call the onRefresh() method of lifecycleProcessor, if it is DefaultLifecycleProcessor, then get all Bean objects of type Lifecycle, then call its start() method, which is ApplicationContext's lifecycle extension mechanism.
  17. Publishing ContextRefreshedEvent events

Tags: Java Spring source code

Posted on Sun, 31 Oct 2021 13:42:57 -0400 by bahewitt