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;

.Copy the code

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

BedefinitionReader BeanDefinitionScanner BeanDefinitionScanner BeanDefinitionScanner 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, Initialize the Environment object this(Registry, getOrCreateEnvironment(Registry)); }

Provides the ability to register BeanDefinitions

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 registration of Beandefinitions later

GetOrCreateEnvironment this method creates and retrieves the internal environment of the pager:

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(); }

Environment objects contain system environment variables, custom attributes and other content.

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 the configuration class this.reader.register(componentClasses); registerComponentClass.end(); }

Reader register (); reader register ()

public void register(Class… componentClasses) { for (Class componentClass : componentClasses) { registerBean(componentClass); } } public void registerBean(Class<? > beanClass) { doRegisterBean(beanClass, null, null, null, null); } private void doRegisterBean(Class beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier supplier, @nullable BeanDefinitionCustomizer[] customizers) {// Convert class objects into beandefinitions, 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 property Settings abd.setInstancesupplier (supplier); // Handle scope, no setting, default return singleton; @scope (“scopeName”) will do that 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 2.@Primary 3.@Role 4.@DependesOn 2.@Primary 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 or beanName. BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); // If @scope sets the proxy, 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) A beanDefinition DefaultListableBeanFactory beanDefinitionMap in in, To deposit beanDefinitionNames beanName BeanDefinitionReaderUtils. RegisterBeanDefinition (definitionHolder, enclosing registry); }

Put the above code together to sort out the general logic of the following doRegisterBean:

Create an AnnotationBeanDefinition of a configuration class object, parse whether Conditional annotations exist on the class by AnnotationBeanDefinition, and judge whether the conditions for registration are met. If not, The Supplier passed in to the registration method in ABD is not registered, and the Scope property can then be resolved through the instantiation of the implementation bean through this interface and registered to the ABD to create the beanName

Create a beanDefinitionHolder that holds correspondence between ABD and beanName, alias handle non-singleton Scope, return a proxy, Detailed in the Scope of processing BeanDefinitionReaderUtils. RegisterBeanDefinition (definitionHolder, enclosing the registry).

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

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 the 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 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

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(); }Copy the code

}

The above code 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 to is the else branch at line 59. The following things were done:

BeanDefinitionMap beanDefinitionNames beanName beanDefinitionNames beanName if there’s beanName in manualSingletonNames, To be removed

Why maintain a separate beanDefinitionNames? Mainly because beanDefinitionMap is unordered, whereas beanDefinitionNames is an ArrayList, which is ordered and can hold bd’s registration order

What does the refresh method do 1. PrepareRefresh

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. // 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 several things:

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

getEnvironment().validateRequiredProperties(); Validation of mandatory properties is provided by the AbstractPropertyResolver interface, of which the Environment object is an implementation.

@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 are no mandatory attributes in the default container. If you need to add the validation, use the beanFactory to fetch the Environment and set it:

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

This 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 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 see what the refreshBeanFactory() does:

@override protected final void refreshBeanFactory() throws IllegalStateException {// The internal container allows refresh 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()); }

The main CAS change has been made to refresh the container to ensure that the container is refreshed only 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: // Check whether the bean implements the following Aware interface. If so, 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 ApplicationListeners 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 into 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()); }Copy the code

} to 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 -> IgnoreDependencyInterface applicationContext. GetApplicationStartup () : Ignore the following interfaces during automatic assembly and realize the following interfaces. The set method can accept the values passed in by aware callback for assembly. If there is more intuitive understanding relative to electron, its format can also be referred to as follows:

Swam: page www.sangpi.com

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);
Copy the code

Add container built – in dependencies. < span style = “box-sizing: block; color: RGB (51, 51, 51); font-size: 14px! Important; word-break: break-all;” But if you specify a specific type of assembly object in resolvableDependencies, you can use the specified object directly. The Spring container has multiple antiphonic objects of type BeanFactory and so on, so the dependency object is specified here to avoid errors. We can also get the Beanfactory through custom BeanFahttp://www.sangpi.com/ctoryPostProcessor, then specify your own types – dependent objects relations.

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

Add ApplicationListenerDetector DestructionAwareBeanPostProcessor: Callback before bean exposure, before providing the bean instance externally, 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 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()); }Copy the code

4.postProcessBeanFactory

Reserved extension method, not implemented by default

5.invokeBeanFactoryPostProcessors(beanFactory)

Here are two things to know about BeanFactoryPostProcesso:

Registered spring BeanFactoryPostProcessor: ConfigurableApplicationContext# addBeanFactoryPostProcessor

What BeanFactoryPostProcessor does:

@FunctionalInterface public interface BeanFactoryPostProcessor {

/ * *

  • Modify the application’s built-in beanFactory before all BeanDefinitions have been loaded and there is no Bean instantiation
  • This method allows you to modify the property configuration of a beanDefinition and even pre-initialize the bean
  • Modify the application context’s internal bean factory after its standard
  • initialization. All bean 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 the built-in BeanFactory is ready in Step 3. 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 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();
Copy the code

} Main process:

Create two list save spring BeanFactoryPostProcessor and BeanDefinitionRegistryPostProcessor respectively Store custom registered BeanFactoryPostProcessors to 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 the command is executed. Here you get one: Org. Springframework. Context. The annotation. InternalConfigurationAnnotationProcessor will currentRegistryProcessors sorting, And put 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. Execute their postProcessBeanFactory method and now there’s a container built in BeanFactoryPostProcessor that’s not handled, that’s also PriorityOrdered, Ordered, The nonOrdered order loads and calls their postProcessBeanFactory method 6.initMessagesource

MessageSource is listed as a panel discussion

7.initApplicationEventMulticaster()

Event broadcast mechanisms are included in the thematic discussion

8.onRefresh

By this point, the whole BeanFactory is ready to go. All that remains is the processing of the bean in the container, after which the onFresh method can perform the callback. In SpringBoot, for example, this method is 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 that we’ll discuss in Chapter 2

conclusion

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