In the last two articles, we have basically examined the XmlBeanFactory application instance. In this chapter, we will examine the ApplicationContext. Bosses skip

Now that the first two articles have covered the basic XmlBeanFactory operation examples, let’s talk about ApplicationContext. As I mentioned before, the basic flow of these two things should be similar. For example, we speculated earlier:

  • Reading configuration Files
  • Find the corresponding class based on the configuration file and instantiate it through reflection
  • It is then stored in the container and retrieved when called

Difference between ApplicationContext and XmlBeanFactory

Can these projections still be used in the source parsing of ApplicationContext? The answer is yes. Earlier we talked about IOC container design and implementation, there are two series, a BeanFactory, an ApplicationContext. So what category does the XmlBeanFactory we looked at earlier fall into? Let’s take a look at the class diagram for XmlBeanFactory

XmlBeanFactory inheritance system is XmlBeanFactory – > DefaultListableBeanFactory – > AbstractAutowireCapableBeanFactory – > AbstractBeanFactory -> FactoryBeanRegistrySupport -> DefaultSingletonBeanRegistry -> SimpleAliasRegistry -> AliasRegistry

But please note: on the basis of DefaultListableBeanFactory XmlBeanFactory did extension. The BeanFactory interface is finally implemented. Our ApplicationContext exists as a high-level form of container. Application context adds many other features to a simple container. Why do you say that? Let’s look at the class diagram for ApplicationContext.

It’s not hard to see that ApplicationContext also implements the BeanFactory, but it’s obvious here that ApplicationContext does more support.

BeanFactory

The BeanFactory is at the heart of Spring. Spring is a huge encapsulation of the BeanFactory, which is really the core of Spring.

BeanFactory provides the most basic IOC container functions, about these functions, we can read his source code

String FACTORY_BEAN_PREFIX = "&";

/** * Get bean */ by name
Object getBean(String name) throws BeansException;

<T> T getBean(String name, Class<T> requiredType) throws BeansException;

<T> T getBean(Class<T> requiredType) throws BeansException;

Object getBean(String name, Object... args) throws BeansException;

/** * whether to include bean */
boolean containsBean(String name);

/** * Check whether the bean is of type Singleton */
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

/** * Check whether the bean is of type Prototype */
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

/** * Queries whether the class type of the bean is a specific class type */
boolean isTypeMatch(String name, Class
        targetType)
        throws NoSuchBeanDefinitionException;

/** * Query the bean's class type */Class<? > getType(String name)throws NoSuchBeanDefinitionException;

/** * Query all aliases of the bean */
String[] getAliases(String name);
Copy the code

It doesn’t have much code, but it provides a specification for using the IOC container. Understanding this will help us understand ApplicationContext, we can think of BeanFactory as a simple container form, and ApplicationContext as a high-level container form.

At this point, we’ve actually seen some differences between XmlBeanFactory and ApplicationContext. But it’s not so obvious here. We might as well take a look at the ApplicationContext its implementation class ClassPathXmlApplicationContext, namely we use inside the code. What’s the difference between one of its sources and XmlBeanFactory

ClassPathXmlApplicationContext

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
    super(parent);
    this.setConfigLocations(configLocations);
    if (refresh) {
        this.refresh(); }}Copy the code

Its initialization is repeated by calling super(parent), but the refresh() method does the initialization of the container.

The code for the refresh() method is as follows

public void refresh(a) throws BeansException, IllegalStateException {
    synchronized(this.startupShutdownMonitor) {
        this.prepareRefresh(); // Preparations
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); / / get ConfigurableListableBeanFactory DefaultListableBeanFactory is the purpose of in the end
        this.prepareBeanFactory(beanFactory); // Prepare the bean factory

        try {
            this.postProcessBeanFactory(beanFactory); // An empty implementation, note that the Spring version number here is 5.3x
            this.invokeBeanFactoryPostProcessors(beanFactory); // Register the bean's factory
            this.registerBeanPostProcessors(beanFactory);
            this.initMessageSource(); // Spring extracts BeanPostProcessor from all @bean definitions and registers them all with beanPostProcessors, waiting for the subsequent sequential calls to register BeanPostProcessor
            this.initApplicationEventMulticaster(); // Initializes the event to listen for multiplexers
            this.onRefresh(); // An empty implementation
            this.registerListeners(); // Register the listener
            this.finishBeanFactoryInitialization(beanFactory); // Start instantiating all BDS in the most complex part of the Spring loading process
            this.finishRefresh();// Refresh to finish the work
        } catch (BeansException var9) {
            if (this.logger.isWarnEnabled()) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
            }

            this.destroyBeans();
            this.cancelRefresh(var9);
            throw var9;
        } finally {
            this.resetCommonCaches(); }}}Copy the code

The methods are generally fairly clear, with a few big ways of summarizing what Refresh () does. We’ll look at these processes in detail later, but here’s a summary.

Position here, we see the ClassPathXmlApplicationContext a process, and our XmlBeanFactory difference is quite big, before we speculate, he should go to load the XML, actually also made here, but in deep hidden, In the details of the second part of the load process, we post the core code here

ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

this.refreshBeanFactory();

this.loadBeanDefinitions(beanFactory);

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    this.initBeanDefinitionReader(beanDefinitionReader);
    this.loadBeanDefinitions(beanDefinitionReader);
}
Copy the code

In fact, the bean initialization and container initialization are also in this process, we will talk about this later, but from our summary, it is not exactly the same as we guessed, just a lot of other things. This extra stuff is what separates our two container implementations.

Conclusion:

  • The basic implementation of the BeanFactory provides the basic IOC container, and the ApplicaitonContext appears in advanced form, adding many additional functions.
  • XmlBeanFactory is one of the most basic applications of our BeanFactory
  • XmlBeanFactory and ClassPathXmlApplicationContext estimate we have process, but the implementation is different, and the specific process, both difference is very big