Spring source code-refresh(1)

1. Introduction to Refresh method

refresh is the core process of Spring, mainly including 13 methods. These 13 methods mainly include 3 main methods.

As shown in the picture:

The ones marked with an asterisk represent the main methods. It can also be seen from the branch data at the end of the method that there is a lot of logical processing in the main method, which we will slowly break down and sort out later.

This chapter mainly summarizes the first four methods.

2. prepareRefresh initializes the context environment

2.1 Initialization Identity
// 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());
}
}

Mark the current Context environment as active and set the closed state to false. Where this is AnnotationConfigApplicationContext. As shown in the picture:

2.2 Verify all attributes and mark them
// Initialize any placeholder property sources in the context environment.
initPropertySources();

// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();

initPropertySources initializes placeholder property sources in the context environment. It is mainly used by subclasses and is empty by default. This is a hook method.

getEnvironment() Gets the environment ConfigurableEnvironment required by the current context. A standard environment is created by default. This environment can obtain environment variables and properties.

validateRequiredProperties() Gets all required properties and saves them into a MissingRequiredPropertiesException object. If the environment is running without detecting the registered required properties, an exception will be thrown.

2.3 Initializing listeners and events

Initialize listeners and events. Be prepared for later release events.

3. obtainFreshBeanFactory()

Get an internal BeanFactory

3.1 Refresh the current factory

The current factory is DefaultListableBeanFactory, and the empty parameter constructor of GenericApplicationContext will create the factory.

Then set the unique identifier of the factory SerializationId

3.2 Return to the current factory

The factory returns an interface ConfigurableListableBeanFactory, and the implementation is still DefaultListableBeanFactory in 3.1

4. prepareBeanFactory()

Configure some features of the factory standard environment.

This method has about 40 lines of code and can be divided into 5 parts:

  • Ignore specified interface

  • Register resolution dependencies

  • Add BeanPostProcessor (BPP)

  • Register the default singleton of the environment

  • Other features

This classification will disrupt the order of some codes in the method, and there will be sequential requirements for the execution of some codes. The following analysis will be organized according to categories.

4.1 Ignore specified interface
beanFactory.ignoreDependencyInterface(xxxx.class)

The ignored interfaces are:

  • EnvironmentAware.class

  • EmbeddedValueResolverAware.class

  • ResourceLoaderAware.class

  • ApplicationEventPublisherAware.class

  • MessageSourceAware.class

  • ApplicationContextAware.clas

  • ApplicationStartupAware.class

Ignore the specified xxxxAware interface. Because the xxxxAware interface provides external extensions, exposing xxxx itself. So BeanFactory does not need to care about these interfaces when processing. Just focus on the actual xxx interface itself.

4.2 Register resolution dependencies

The processing of BeanFactory.class, ResourceLoader.class, ApplicationEventPublisher.class, and ApplicationContext.class depends on the current Bean factory, so a corresponding relationship is established. Essentially, it is to maintain a one-to-one map collection. Get it directly when it is convenient to use.

4.3 Add BPP

BeanPostProcessor is the post-processor for Bean initialization. It can be enhanced before and after Bean initialization.

  • new ApplicationContextAwareProcessor(this) Context Aware processor

    Before bean initialization, process the class that implements the Aware interface and set up the environment and parser for it.

  • new ApplicationListenerDetector(this) The detector of the listener

    This class implements the DestructionAwareBeanPostProcessor MergedBeanDefinitionPostProcessor interface. Called after merging the Bean definition, after the Bean is instantiated, and before the Bean is destroyed.

    If the current Bean is ApplicationListener, the corresponding logic will be executed.

  • new LoadTimeWeaverAwareProcessor(beanFactory) Code weaving at compile time

    Set LoadTimeWeaver for a bean before it is initialized

4.4 Register the default singleton

Registered singleton:

  • environment standard configuration environment

  • systemProperties system properties

  • systemEnvironment system environment

  • Bean started by applicationStartup

4.5 Other features

Set other properties for BeanFactory

beanFactory.setBeanClassLoader(getClassLoader());

Set up a class loader to load some configuration files and other information

beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()))

Set the parser for a bean’s EL expression

beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

Set the property editor registrar.

When dealing with the correspondence between strings and dates, we can register the correspondence between String and Date, etc.

5. postProcessBeanFactory(beanFactory)

Hook function reserved for subclasses, empty implementation by default. It will be used when springboot starts (increasing the processor of the web container).