ioc boot
@SpringBootApplication public class Application { public static void main(String[] args) { // Manually enable an ioc container FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("src/main/resources/spring-bean.xml"); } }
The source code of FileSystem Xml Application Context is as follows:
public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext { public FileSystemXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); // Setting the location of xml configuration information setConfigLocations(configLocations); if (refresh) { // Method of starting ioc container refresh(); } } }
It can be seen that refresh() is the completion of the start-up of the ioc container, the detailed source code is as follows:
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. // Pre-refresh processing, such as labeling environment startup time, labeling environment startup identifier active = true, labeling environment shutdown identifier close = false, etc. // active and close labels are modified with atomic to maintain atomicity prepareRefresh(); // Tell the subclass to refresh the internal bean factory. // Get a new, clean container // Call the refreshBeanFactory() method first // Delete the old container, create a new container, initialize it, etc., and return to the new container. // In the refreshBeanFactory method, load the BeanDefinition information ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // Standard environment properties for configuring containers, such as context's classLoader or poseProcessor prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // Postprocessing of Configuration Containers postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. // Post-processor calling BeanFactory invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // The post-processor of the registered bean is called during the bean creation process registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // Initialization information source initMessageSource(); // Initialize event multicaster for this context. // Time mechanism in initialization context initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // Initialize some special bean s onRefresh(); // Check for listener beans and register them. // Check listener bean s and register them in containers registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. // Initialize all non-lazy loaded bean s finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // Publish container end events finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
BeanDefinition load
BeanDefinition is loaded at Configurable Listable BeanFactory BeanFactory = obtainFreshBeanFactory(). In the obtainFreshBeanFactory() method, refreshBeanFactory() is first loaded. The source code is as follows:
protected final void refreshBeanFactory() throws BeansException { // If there is a bean Factory, it means whether to hold defaultListable beanFactory or not. if (hasBeanFactory()) { // Destroy all singleton bean s in the container // The source code actually puts beans and information about beans into hashMap or ConCurrent HashMap in the container, and then clears these maps. destroyBeans(); // Close container // Set the Default Listable BeanFactory held by the container to null closeBeanFactory(); } try { // new defaultListable BeanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); // Custom Container Settings Some Properties of Containers customizeBeanFactory(beanFactory); // Set up definitionReader, resourceLoader, entity Resolver, etc., and handle BeanDefinition after aspect loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
Determine if a container already exists. If it already exists, destroy the singleton bean s in the container first, and then close the container. After creating a DefaultListableBeanFactory from scratch, and then setting some corresponding properties, the loadBeanDefinitions will begin.