The target

Trace the flow of the following code:

AnnotationConfigApplicationContextDemo

/**

 * description

 * date 2021-06-30 11:21

 **/

public class AnnotationConfigApplicationContextDemo {

public static void main(String[] args) {
    final AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SimpleConfig.class);
    User user = applicationContext.getBean(User.class);
    System.out.println("user:" + user);
}

}

Configuration

public class SimpleConfig {

Bean
public User user(){
    return new User("xgimi", 10);
}

}

public class User {

private String name;
private Integer age;

.

process

The core logic are AnnotationConfigApplicationContext take participate in the constructor:

public AnnotationConfigApplicationContext(Class<? >... componentClasses) { this(); register(componentClasses); refresh(); }

What does the empty constructor do

First answer: two things, one is to create bedefinitionReader, beandefinitionScanner, to provide the ability to scan beanDefinition; 2 it is through the constructor of the superclass GenericApplicationContext created DefaultListableBeanFactory, provide the underlying ability of the IOC.

Initialize AnnotatedBeanDefinitionReader

Public AnnotatedBeanDefinitionReader (BeanDefinitionRegistry registry) {/ / into the registry, And initializes the Environment object this(Registry, GetOrcreateEnvironment (Registry)); }

Provides the ability to register BeanDefinition

public AnnotationConfigApplicationContext() {
    StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
    this.reader = new AnnotatedBeanDefinitionReader(this);
    createAnnotatedBeanDefReader.end();
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}



We will explore the nature of BeanDefinitionRegistry to register BeanDefinition later

GetOrcreateEnvironment This method creates the internal environment of the page game and gets:

private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    if (registry instanceof EnvironmentCapable) {
        return ((EnvironmentCapable) registry).getEnvironment();
    }
    return new StandardEnvironment();
}



The environment object contains system environment variables, custom properties and so on.

Through the constructor as you can see, AnnotatedBeanDefinitwww.sangpi.com ionReader underlying maintains a BeanDefinitionRegistry. In fact, he is to provide the ability of registration by BeanDefinitionRegistry AnnotationConfigApplicationContext itself is a BeanDefinitionRegistry; So the call AnnotatedBeanDefinitionReader constructor, we incoming is AnnotationConfigApplicationContext:

Is actually the combination relationship, the ability of most of AnnotationConfigApplicationContext, including registered beanDefinition, rely on search, dependency injection, is through DefaultListableBeanFactory through the bottom of the ability to support.

How do I register a configuration class as a BeanDefinition

In AnnotationConfigApplicationContext:

Override public void register(Class<? >... componentClasses) { Assert.notEmpty(componentClasses, "At least one component class must be specified"); StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register") .tag("classes", () -> Arrays.toString(componentClasses)); // Register this.reader.register(componentClasses); registerComponentClass.end(); }

As you can see from the above code, it is mainly registered by calling the register method of Reader. Let’s take a look at the implementation logic of this method

public void register(Class<? >... componentClasses) { for (Class<? > componentClass : componentClasses) { registerBean(componentClass); } } public void registerBean(Class<? > beanClass) { doRegisterBean(beanClass, null, null, null, null); } private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] Customizers) {// Class protected by BeanDefinition; The only class in this BeanDefinition information and commentary on the class notes AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass); / / @ Conditional annotate the if (this. ConditionEvaluator. ShouldSkip (abd) for getMetadata ())) {return; } // Supplier takes precedence over all constructor and factory methods for class instantiation, but does not affect the property setting abd.setInstanceUpplier (supplier); // return singleton; // return singleton; @scope ("scopeName") is handled in this method, Get scopeName ScopeMetadata ScopeMetadata = this. ScopeMetadataResolver. ResolveScopeMetadata (abd); abd.setScope(scopeMetadata.getScopeName()); / / create beanName AnnotationBeanNameGenerator provide capacity, but gives priority to the String to interface into the ginseng beanName = (the name! = null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); // Set the values of the following annotations to abd //1.@Lazy 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); }} // DefinitionHolder holds beanDefinition and beanName(you can also have aliases) BeanDefinitionHolder(abd, beanName); // If @Scope has the proxy set, It will return a proxy object definitionHolder = AnnotationConfigUtils. ApplyScopedProxyMode (scopeMetadata definitionHolder, this.registry); / / will definitionHolder beanDefinition registered to the registry of object / / DefaultListableBeanFactory registerBeanDefinition (String beanName, BeanDefinition BeanDefinition) // final result: A beanDefinition DefaultListableBeanFactory beanDefinitionMap in in, To deposit beanDefinitionNames beanName BeanDefinitionReaderUtils. RegisterBeanDefinition (definitionHolder, enclosing registry); }

To summarize the above code, summarize the logic of the following DoRegisterBean:

Create a annotationBeanDefinition that defines the annotationBeanDefinition for an object in the Construct class and use it to determine if there are any Conditional annotations on the class, and if not, Instead of registering the method into an incoming Supplier in ABD, we can then implement the bean instantiation through this interface to resolve the Scope property and register it in ABD to create a beanName

Create a beanDefinitionHolder to hold abd and beanName, the correspondence between alias handles non-singleton scopes, returns a proxy, Detailed in the Scope of processing BeanDefinitionReaderUtils. RegisterBeanDefinition (definitionHolder, enclosing the registry).

Let’s take a look at step 9, exactly how to register:

BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);

public static void registerBeanDefinition(

BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // Register bean definition under primary name. String beanName = definitionHolder.getBeanName(); registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); // Register aliases for bean name, if any. String[] aliases = definitionHolder.getAliases(); if (aliases ! = null) { for (String alias : aliases) { //TODO registry.registerAlias(beanName, alias); }}}

As you can see, there are actually two parts of registration:

Register beanName Register alias

Results found that still use DefaultListableBeanFactory for registration, It also demonstrates our conclusions about the relation between DefaultListableBeanFactory and AnnotationConfigApplicationContext above. To see how to realize in DefaultListableBeanFactory:

@Override

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); if (existingDefinition ! = null) { if (! isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } else if (existingDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (logger.isInfoEnabled()) { logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (! beanDefinition.equals(existingDefinition)) { if (logger.isDebugEnabled()) { logger.debug("Overriding bean definition for  bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else { if (logger.isTraceEnabled()) { logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; removeManualSingletonName(beanName); } } else { // Still in startup registration phase

// The main point is here

            this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
            removeManualSingletonName(beanName);
        }
        this.frozenBeanDefinitionNames = null;
    }
    if (existingDefinition != null || containsSingleton(beanName)) {
        resetBeanDefinition(beanName);
    }
    else if (isConfigurationFrozen()) {
        clearByTypeCache();
    }
}



The above code first checks whether the BD has been registered in the container, and then checks whether the DB is being registered. And we’re registering for the first time, so the core branch we’re going to go through is the else branch starting at line 59. I did the following things:

I put a beanDefinition in beanName which is the key in beanDefinitionMap and I put a beanName in beanDefinitionNames if there’s a beanName in manualSingleName, To be removed

Why maintain a separate beanDefinitionNames? The main reason is that beanDefinitionMap is unordered, while beanDefinitionNames is an ArrayList that is ordered and saves the registration order of BD

What does the Refresh method do 1

protected void prepareRefresh() { // Switch to active. this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isDebugEnabled()) { if (logger.isTraceEnabled()) { logger.trace("Refreshing " + this); } else { logger.debug("Refreshing " + getDisplayName()); }} // Initialize any placeholder property sources in the context environment. // InitPropertySources (); // Validate that all properties marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties(); // Store pre-refresh ApplicationListeners... if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); } else { // Reset local application listeners to pre-refresh state. this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... this.earlyApplicationEvents = new LinkedHashSet<>(); }

The pre-refresh phase mainly does the following things:

Provide initPropertySources external resources () extension methods for container loading, the default is an empty implementation in AnnotationContextApplicationContext

getEnvironment().validateRequiredProperties(); The ability to check required properties is provided by the interface AbstractPropertyResolver, and the Environment object is the implementation of this interface.

@Override
public void validateRequiredProperties() {
    MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
    for (String key : this.requiredProperties) {
        if (this.getProperty(key) == null) {
            ex.addMissingRequiredProperty(key);
        }
    }
    if (!ex.getMissingRequiredProperties().isEmpty()) {
        throw ex;
    }
}

There is no required property in the default container. If you need to add this validation, you can get it from the BeanFactory to the Environment and then set it:

    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
    applicationContext.register(SimpleConfig.class);
    applicationContext.getEnvironment().setRequiredProperties("system");
    applicationContext.refresh();

Is actually the following method of the AbstractPropertyResolver class called

@Override public void setRequiredProperties(String... requiredProperties) { Collections.addAll(this.requiredProperties, requiredProperties); }

RequiredProperties is a LinkedHashSet

private final Set<String> requiredProperties = new LinkedHashSet<>();



EarlyApplicationListeners created in the container, 2 earlyApplicationEvents obtainFreshBeanFactory

Through the return value of this method can judge he obtained the container is built-in ConfigurableListableBeanFactory, we came to see him is how to obtain:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
}



Among them: GetBeanFactory () method is well understood, he is saved in GenericApplicationContext DefaultListableBeanFactory returns, The DefaultListableBeanFactor is instantiated in GenericApplicationContext empty constructor. Let’s look at what refreshBeanFactory() does:

@Override protected final void refreshBeanFactory() throws IllegalStateException {// Refresh the inner container only once if (! this.refreshed.compareAndSet(false, true)) { throw new IllegalStateException( "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once"); } this.beanFactory.setSerializationId(getId()); }

6. You’ve completely changed the CAS to ensure that the container will only be refreshed once

3.prepareBeanFactory(beanFactory)

The preparation phase of the container

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {

// Tell the internal bean factory to use the context's class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); if (! ShouldIgnoreSpel) {// Set the EL expression parser (#{... }) the beanFactory. SetBeanExpressionResolver (new StandardBeanExpressionResolver (the beanFactory. GetBeanClassLoader ())); } / / set properties parser PropertyEditorRegistrar the beanFactory. AddPropertyEditorRegistrar (new ResourceEditorRegistrar (this, getEnvironment())); / / Configure the bean factory with the context callbacks. / / as the container, add a ApplicationContextAwareProcessor This is the first container to add BeanPostProcessor / / ApplicationContextAwareProcessor role: // Determine if the bean implements the following Aware interface. If it does, The corresponding built-in bean or singleton object is assigned to the bean / / 1. EnvironmentAware - > applicationContext. GetEnvironment () / / 2. EmbeddedValueResolverAware - > embeddedValueResolver //3.ResourceLoaderAware -> applicationContext //4.ApplicationEventPublisherAware -> applicationContext //5.MessageSourceAware -> applicationContext //6.ApplicationContextAware -> applicationContext //7.ApplicationStartupAware -> applicationContext.getApplicationStartup() beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class); // BeanFactory interface not registered as resolvable type in a plain factory. // MessageSource registered (and found for autowiring) as a bean. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as ApplicationListener beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. if (! NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // Register Default Environment Beans. // Inject the following singleton in the BeanFactory if (! beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (! beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME,  getEnvironment().getSystemProperties()); } if (! beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } if (! beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) { beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup()); }}

Set this setting el expression parser setting PropertyEditorRegistrar add a ApplicationContextAwareProcessor whether bean implements the following Aware interface, if implemented, The corresponding built-in bean or singleton object is assigned to the bean 1. EnvironmentAware – > applicationContext. GetEnvironment () 2. EmbeddedValueResolverAware – > embeddedValueResolver 3.ResourceLoaderAware -> applicationContext 4.ApplicationEventPublisherAware -> applicationContext 5.MessageSourceAware -> applicationContext 6.ApplicationContextAware -> applicationContext 7.ApplicationStartupAware -> ApplicationContext. GetApplicationStartup () ignoreDependencyInterface: ignore these interfaces when automatic assembly, implements the following interface, can set methods accept aware callback incoming values are assembled

    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);



Add container built-in dependencies. The built-in dependencies of the container will be saved in resolvableDependencies, which supports dependency injection through type. The main problem to be solved is that there are multiple dependency objects of the same type. Spring will report an error during auto-assembly. However, if a specific type of assembly object is specified in ResolvableDependencies, the specified object can be used directly. The Spring container has multiple couplet objects of type BeanFactory, so the dependency object is specified here to avoid errors. We can also obtain the BeanFactory by customizing the BeanFactoryPostProcessor and then specify our own type-dependent object relationship.

    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);






Add ApplicationListenerDetector DestructionAwareBeanPostProcessor: Bean exposure callback, before the bean instance is provided to the public, Can return a proxy object to replace beanMergedBeanDefinitionPostProcessor class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {

Register four singleton objects directly

// Register Default Environment Beans. // Inject the following singleton object in the BeanFactory if (! beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (! beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME,  getEnvironment().getSystemProperties()); } if (! beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } if (! beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) { beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup()); }

4.postProcessBeanFactory

The reserved extension method is not implemented by default

5.invokeBeanFactoryPostProcessors(beanFactory)

BeanFactor PostProcesso, let’s first understand the following two points:

Registered spring BeanFactoryPostProcessor: ConfigurableApplicationContext# addBeanFactoryPostProcessor

BeanFactoryPostProcessor does:

@FunctionalInterface

public interface BeanFactoryPostProcessor {

/** * This method can be used to modify the BeanDefinition property configuration of the application before all BeanDefinition properties are loaded and the Bean is not instantiated. You can even Modify the application context's internal bean factory after its standard * initialization. All beans definitions will have been loaded, but no beans * will have been instantiated yet. This allows for overriding or adding * properties even to eager-initializing beans. * @param beanFactory the bean factory used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

In short, after Step 3 has prepared the built-in BeanFactory. Give the user a chance to get to the beanFactory invokeBeanFactoryPostProcessors process, then we research the default container is not registered here spring BeanFactoryPostProcessor, but this method has other function

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
    // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
    if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

getBeanFactoryPostProcessors()

public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
    return this.beanFactoryPostProcessors;
}

PostProcessorRegistrationDelegate

public static void invokeBeanFactoryPostProcessors(

        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    // WARNING: Although it may appear that the body of this method can be easily
    // refactored to avoid the use of multiple loops and multiple lists, the use
    // of multiple lists and multiple passes over the names of processors is
    // intentional. We must ensure that we honor the contracts for PriorityOrdered
    // and Ordered processors. Specifically, we must NOT cause processors to be
    // instantiated (via getBean() invocations) or registered in the ApplicationContext
    // in the wrong order.
    //
    // Before submitting a pull request (PR) to change this method, please review the
    // list of all declined PRs involving changes to PostProcessorRegistrationDelegate
    // to ensure that your proposal does not result in a breaking change:
    // %3Aclosed+label%3A%22status%3A+declined%22
    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    Set<String> processedBeans = new HashSet<>();
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                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.
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
        // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
        currentRegistryProcessors.clear();
        // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
        currentRegistryProcessors.clear();
        // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    reiterate = true;
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
            currentRegistryProcessors.clear();
        }
        // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        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!
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    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.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    // Finally, invoke all other BeanFactoryPostProcessors.
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    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();
}

Main process:

Create two list save spring BeanFactoryPostProcessor and BeanDefinitionRegistryPostProcessor respectively The custom registered BeanFactoryPostProcessor is stored in RegularPostProcessors or RegistryProcessors by type, and: If it is BeanDefinitionRegistryPostProcessor, Direct call its postProcessBeanDefinitionRegistry method to create a new list to store the container built-in BeanDefinitionRegistryPostProcessor Through BeanDefinitionRegistryPostProcessor type and container PriorityOrdered gets the corresponding beans, add currentRegistryProcessors, and put the name in a processedBeans, Indicates that it has been executed. Here you get one: Org. Springframework. Context. The annotation. InternalConfigurationAnnotationProcessor will currentRegistryProcessors sorting, And put it in RegistryProcessors Traversal of executive currentRegistryProcessors BeanDefinitionRegistryPostProcessor postProcessBeanDefinitionRegistry method Here will perform internalConfigurationAnnotationProcessor callback method, this kind of follow-up will be special research, The result is that the configuration class Bean method corresponding class loading into the container is registered as a bd to empty currentRegistryProcessors repeat 4-8, Call interface is realized Ordered BeanDefinitionRegistryPostProcessor repeat 4-8, call no sort of interface BeanDefinitionRegistryPostProcessor through the operation of the above, All BeanDefinitionRegistryPostProcessor joined registryProcessors, all custom spring BeanFactoryPostProcessor joined regularPostProcessors. The PostProcessBeanFactory method that executes them now has the container’s built-in BeanFactoryPostProcessor unprocessed, also as PriorityOrdered, Ordered, NonOrdered orders load and call their PostProcessBeanFactory method 6. InitMessageSource in turn

MessageSource is listed as a topic

7.initApplicationEventMulticaster()

Event broadcasting mechanisms are included in the discussion

8.onRefresh

At this point, the entire BeanFactory is ready. All that remains is the processing of the beans in the container, and before that, the callback can be performed through the onFresh method. For example, in SpringBoot, this is the method used to start the embedded Web container

9.registerListeners()

Registered container built-in listener implements the interface ApplicationListener class 10. InishBeanFactoryInitialization (the beanFactory)

The process of instantiating all non-lazy loaded singleton beans is again a very complex logic, which we’ll discuss in Chapter 2

conclusion

After the above steps, the Spring container has been initialized and the BeanFactory is ready. The extended features provided by ApplicatiionContext: event mechanisms, resources, AOP capabilities, etc., have also been initialized