• preface

    We created the context object, initialized the bean’s factory class, and loaded the support classes for some annotations. This article will continue to introduce further information perfection of context objects on this basis.

    The article is based on the source code of the SpringBoot2.3. x series (most of the source code in the JAR package as an example to explain), github source and the actual release may be slightly different, but the overall process is not much different. I write an article for the first time, if there is a mistake or misleading welcome comment correction. The article as a whole may be wordy, but try to cover every important aspect of the process.

1. prepareContext

Source:

``` private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {// Inject the environment attribute context.setenvironment (environment); / / rear context handle this. PostProcessApplicationContext (context); // Complete initializers in the class this.applyInitializers(context); / / send to monitor event listeners. ContextPrepared (context). If (this.logStartupInfo) {this.logStartupInfo(context.getParent() == null); // Log if (this.logStartupInfo) {this.logStartupInfo(context.getparent () == null); this.logStartupProfileInfo(context); } // Register the configuration arguments passed in as bean, encapsulating the parameters as applicationArguments, Internal similar command-line ConfigurableListableBeanFactory the beanFactory = context. GetBeanFactory (); beanFactory.registerSingleton("springApplicationArguments", applicationArguments); //banner prints if (printedBanner! = null) { beanFactory.registerSingleton("springBootBanner", printedBanner); } / / by default bean definitions here are not allowed to repeat the if (the beanFactory instanceof DefaultListableBeanFactory) { ((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } / / the default opens the lazy loading the if (this. LazyInitialization) {context. AddBeanFactoryPostProcessor (new LazyInitializationBeanFactoryPostProcessor()); } // Get all the resources // Get the resources of the start class and the source resources in the current SpringApplication. Set<Object> sources = this.getallSources (); Assert.notEmpty(sources, "Sources must not be empty"); this.load(context, sources.toArray(new Object[0])); listeners.contextLoaded(context); } ` ` `Copy the code

Do the same thing, one by one. But look at this method is not complicated, overall the context and factory class configuration is complete.

1.1 postProcessApplicationContext method

Source:

Protected void postProcessApplicationContext (ConfigurableApplicationContext context) {/ / whether the custom bean name if generated class (this.beanNameGenerator ! = null) { context.getBeanFactory().registerSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerato r", this.beanNameGenerator); } // Whether to specify class loader if (this.resourceloader! = null) { if (context instanceof GenericApplicationContext) { ((GenericApplicationContext)context).setResourceLoader(this.resourceLoader); } if (context instanceof DefaultResourceLoader) { ((DefaultResourceLoader)context).setClassLoader(this.resourceLoader.getClassLoader()); }} // Whether to add a data converter // also useful when initializing the environment object, Here can be directly through the context. GetEnvironment () getConversionService () to get the if (this. AddConversionService) { context.getBeanFactory().setConversionService(ApplicationConversionService.getSharedInstance()); }}Copy the code

1.2 applyInitializers

Perfect ApplicationContextInitializer interface related object properties, at the same time, it can be configured to context properties. These objects are already loaded in the this.initializers when the SpringApplication is initialized. Refine related classes with the context already initialized. Call the initialize method of the interface.

1.3 the load

Source:

protected void load(ApplicationContext context, Object[] sources) { if (logger.isDebugEnabled()) { logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources)); } / / build a bean definition of loader BeanDefinitionLoader loader = createBeanDefinitionLoader (getBeanDefinitionRegistry (context), sources); if (this.beanNameGenerator ! = null) { loader.setBeanNameGenerator(this.beanNameGenerator); } if (this.resourceLoader ! = null) { loader.setResourceLoader(this.resourceLoader); } if (this.environment ! = null) { loader.setEnvironment(this.environment); } // Load the resource into bean loader.load(); } void load() { for (Object source : this.sources) { load(source); }} private void load(Object source) {assert. notNull(source, "source must not be null"); if (source instanceof Class<? >) { load((Class<? >) source); return; } if (source instanceof Resource) { load((Resource) source); return; } if (source instanceof Package) { load((Package) source); return; } if (source instanceof CharSequence) { load((CharSequence) source); return; } throw new IllegalArgumentException("Invalid source type " + source.getClass()); }Copy the code

The main loading of resources initialized within SpringApplication, including our startup class xxApplication, will be registered as a bean.

summary

After the context is created, some properties are initialized and some configuration resources are loaded.