This is the sixth day of my participation in the August More text Challenge. For details, see:August is more challenging

preface

The last article covered the general process of Spring container initialization, but this time I’ll take a closer look at some of the processes.

The body of the

Look at the first few processes in the Spring container creation process:

/ / classes and methods: AbstractApplicationContext. Refresh () / / Prepare this context for refreshing. PrepareRefresh (); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory);Copy the code

prepareRefresh

The comment above the method is also clear: To prepare the context for the refresh, enter the method source:

// Class and method: AbstractApplicationContext.prepareRefresh() protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); This.closed. Set (false); // Set the container closed status to 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 are marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties(); // Store pre-refresh ApplicationListeners... / / initialize storage ApplicationListeners if (this. EarlyApplicationListeners = = null) {enclosing 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... / / initialize storage earlyApplicationEvents enclosing earlyApplicationEvents = new LinkedHashSet < > (); }Copy the code

This.startupdate, this.closed. Set (false), this.active. Set (true), applicationListeners, and other listeners EarlyApplicationListeners earlyApplicationEvents these attributes.

Notice the initPropertySources method, which has no action by default, but there are three classes that implement it under the Spring-Web package.

ObtainFreshBeanFactory method

The source code for this method is also relatively simple:

// Class and method: AbstractApplicationContext.obtainFreshBeanFactory protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // refreshBeanFactory refreshBeanFactory(); // Return getBeanFactory(); }Copy the code

In AbstractApplicationContext class, the two methods above are interface, from the previous article, using the AnnotationConfigApplicationContext, inheriting from a class diagram can know, GenericApplicationContext class is implementation for the above two methods, direct positioning to GenericApplicationContext class:

/ / class: GenericApplicationContext @ Override protected final void refreshBeanFactory () throws an IllegalStateException {the if (! this.refreshed.compareAndSet(false, True)) {/ / cas modify refreshed state throw new an IllegalStateException (" GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once"); } this.beanFactory.setSerializationId(getId()); } @Override public final ConfigurableListableBeanFactory getBeanFactory() { return this.beanFactory; }Copy the code

Both of these methods are relatively simple,

  1. The refreshBeanFactory method changes the refreshed value using cas, changes it to true, and then assigns the refreshed ID to the refresh ID
  2. GetBeanFactory easier, in the method of constructing the beanFactory attribute is initialized to DefaultListableBeanFactory, so here return DefaultListableBeanFactory;

Also, the debug method indicates that the beanFactory has only a few beans in it. Not all beans are registered, so the automatic discovery of beanFactory (scanning for bean information) does not occur here.

PrepareBeanFactory method

To prepare a beanFactory, you just assign a bunch of properties to the beanFactory;

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); / / set the class loader. The beanFactory setBeanExpressionResolver (new StandardBeanExpressionResolver (the beanFactory. GetBeanClassLoader ())); / / set expression parser. The beanFactory addPropertyEditorRegistrar (new ResourceEditorRegistrar (this, getEnvironment ())); // Configure the beanFactory with context callbacks. // Configure the beanFactory with context callbacks 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 interface not registered as resolvable type in a plain factory. // MessageSource registered (and found For autowiring) as a bean. / / add automatically discover and support the beanFactory injection. RegisterResolvableDependency (the beanFactory. Class, the 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 (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. // Register default environment information 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()); }}Copy the code

This method is more complicated and sets many properties of the beanFactory.

The last

Ok, beanFactory’s preprocessing is almost complete, now it’s time to post processing.