preface

The difference between ApplicationContext and BeanFactory in Spirng is explained in the official documentation.

The org. Springframework. Beans and org. Springframework. Context packages are The basis for Spring Framework 's IoC container. The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext is a sub-interface of BeanFactory. It adds: Easier integration with Spring's AOP features Message resource Handling (for use in internationalization) Event publication Application-layer specific contexts such as the WebApplicationContext for use in web applications.Copy the code

The point of the documentation is that ApplicationContext adds a lot of functionality to the BeanFactory, but the understanding of these interfaces is still not deep enough, so I’m going to take a look at how SpringBoot uses these interfaces.

ApplicationContext

Initialization of ApplicationContext

It all starts with SpringBoot boot, where different contexts are created for different application types:

protected ConfigurableApplicationContext createApplicationContext(a) { Class<? > contextClass =this.applicationContextClass;
		if (contextClass == null) {
			try {
				switch (this.webApplicationType) {
				case SERVLET:
					contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
					break;
				case REACTIVE:
					contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
					break;
				default: contextClass = Class.forName(DEFAULT_CONTEXT_CLASS); }}catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass", ex); }}return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
	}
Copy the code

If it is the SERVLET will create AnnotationConfigServletWebServerApplicationContext types of context (is also discussed to switch type).

AnnotationConfigServletWebServerApplicationContext class Diagram in figure

AbstractApplicationContext

AbstractApplicationContext ConfigurableApplicationContext interface is realized.

/**
 * SPI interface to be implemented by most if not all application contexts.
 * Provides facilities to configure an application context in addition
 * to the application context client methods in the
 * {@link org.springframework.context.ApplicationContext} interface.
 *
 * <p>Configuration and lifecycle methods are encapsulated here to avoid
 * making them obvious to ApplicationContext client code. The present
 * methods should only be used by startup and shutdown code.
 */
Copy the code

This interface provides the ability to configure the application context. The interface and a more important way of org. Springframework. Context. ConfigurableApplicationContext# refresh, AbstractApplicationContext abstract classes in the implementation method is as follows :

public void refresh(a) throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 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);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				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(); }}}Copy the code

Will refresh () method in the org. Springframework. Boot. SpringApplication# refresh method call

  protected void refresh(ApplicationContext applicationContext) {
      Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
      ((AbstractApplicationContext) applicationContext).refresh();
  }
Copy the code

The refresh() method documentation explains that after executing this method, all singletons are instantiated.

GenericApplicationContext

/** * Generic ApplicationContext implementation that holds a single internal * {@link org.springframework.beans.factory.support.DefaultListableBeanFactory} * instance and does not assume a specific bean definition format. Implements * the {@link org.springframework.beans.factory.support.BeanDefinitionRegistry} * interface  in order to allow for applying any bean definition readers to it. */Copy the code

GenericApplicationContext hold DefaultListableBeanFactory instance, and implements the BeanDefinitionRegistry interface provides BeanDefinition add, delete, check function.

GenericApplicationContext.java

private final DefaultListableBeanFactory beanFactory;

public GenericApplicationContext(a) {
	this.beanFactory = new DefaultListableBeanFactory();
}
Copy the code

From GenericApplicationContext initialized in the constructor of the DefaultListableBeanFactory, To BeanDefinition to add, delete, check the function of the entrusted to the DefaultListableBeanFactory object implementation. Actually in AbstractApplicationContext’s ability to find the bean is realized

AbstractApplicationContext.java

	@Override
	public Object getBean(String name) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(name);
	}
Copy the code

But genBeanFactory (), is an abstract method in AbstractApplicationContext GenericApplicationContext implements the method

GenericApplicationContext.java

	@Override
	public final ConfigurableListableBeanFactory getBeanFactory(a) {
		return this.beanFactory;
	}
Copy the code

We often look up a Bean when writing Spring test code as follows:

public class CdtftApplication {

	public static void main(String[] args) {
		ApplicationContext context = new AnnotationConfigApplicationContext("github.cdtft");
		MyTestBean myTestBean = (MyTestBean) context.getBean("myTestBean"); System.out.println(myTestBean); }}Copy the code

Really its capability of providing this lookup is DefaultListableBeanFactory behind it.

conclusion