Spring has to mention its two major features IOC, AOP, this article mainly introduces the combination of code to see spring IOC related principles, read the source code if only to see the source code efficiency will be very low, or to have a certain purpose, we combined the following questions to source code to find the answer. This article is a Turing House course note

  • How does a Bean factory produce beans
  • Who resolves the Bean’s dependencies
  • Bean factory and application context

As can be seen from the overall architecture of Spring Ioc in the figure below, Spring reads the bean configuration information when it starts, generates a corresponding bean configuration registry in Spring, then instantiates beans according to the registry, and assembles the bean dependencies to provide bean instances for upper-layer applications. The cache pool for the beans is implemented via hashMap

The build process of the bean

The description configuration of the Bean is stored in Spring. XML, and the BeanFactory reads the configuration and generates the Bean. This is our general understanding of ioc principles, and further thinking leads to more problems

  • Which Java object hosts the contents of the configuration information
  • These host objects read the configuration file and load it
  • Where are these load objects stored

BeanDefinition = Bean definition

In the IOC implementation, the Bean information we describe in XML is eventually stored in the BeanDefinition object, where the XML Bean has a one-to-one relationship with the BeanDefinition procedure. Properties set in an XML bean will end up in the BeanDefinition

As you can see, the properties set in the XML bean end up in the BeanDefinition. Such as:

**XML-bean ** BeanDefinition
class beanClassName
scope scope
lazy-init lazyInit
constructor-arg ConstructorArgument
property MutablePropertyValues
factory-method factoryMethodName
destroy-method AbstractBeanDefinition.destroyMethodName
init-method AbstractBeanDefinition.initMethodName
autowire AbstractBeanDefinition.autowireMode
id
name

BeanDefinition property structure

Definitionregistry (DefinitionRegistry)

In the preceding table, we did not see that the ID and name attributes in the XML bean were not included in the definition, because id was registered with the BeanDefinitionRegistry as the storage key for the current bean. Name is registered in the AliasRegistry as the alias key. It all ends up pointing to its BeanDefinition.

BeanDefinitionRegistry attribute structure

Definitionreader (DefinitionReader);

Let’s see if BeanDefinition holds Xml Bean information, and if BeanDefinitionRegister holds the Bean definition based on ID and name. Next, you need to learn how to go from XML Beans to BeanDefinition and then register with BeanDefinitionRegister.

BeanDefinitionReader reads configuration from XML, builds BeanDefinitionReader, and registers it with BeanDefinitionRegister based on aliases.

BeanDefinitionReader structure

  • int loadBeanDefinitions(Resource var1)

Load the beanDefinition based on the resource and register it with the registry

  • int loadBeanDefinitions(String var1)

    Load the beanDefinition based on the resource path and register the large screen registry

  • BeanDefinitionRegistry getRegistry()

    Get the registry

  • ResourceLoader getResourceLoader()

Get the resource loader

Example for loading BeanDefinitionReader

// Create a simple registry
BeanDefinitionRegistry register = new SimpleBeanDefinitionRegistry();
// Create a bean definition reader
BeanDefinitionReader reader = new XmlBeanDefinitionReader(register);
// Create a resource reader
DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
// Get resources
Resource xmlResource = resourceLoader.getResource("spring.xml");
// Load the Bean definition
reader.loadBeanDefinitions(xmlResource);
// Print the name of the built Bean
System.out.println(Arrays.toString(register.getBeanDefinitionNames());
Copy the code

The Beanfactory (bean factory)

Having the Bean definition is equivalent to having the recipe for the product, and the next step is to send the recipe to the factory for production. The building of beans in IOC is the responsibility of the BeanFactory. Its structure is as follows:

Method description:

  • getBean(String)
    • Gets a Bean based on ID or name
  • T getBean(Class requiredType) 
    • Get a Bean based on the class of the Bean (an error will be reported if multiple instances of the class occur. This error can be resolved by specifying primary= “true” to adjust the priority.
  • Object getBean(String name, Object… args)
    • Gets a Bean based on its name and overrides the default construction parameters
  • boolean isTypeMatch(String name, Class<? > typeToMatch)
    • Specifies whether the Bean matches the specified Class

The main concern in the above method is getBean. When the user calls getBean, it triggers the creation of the Bean. How is it created?

Demonstrates how the basic BeanFactory gets a Bean

# to create / / its reflection instantiation Bean Java Bean stack. Lang. Reflect. Constructor. NewInstance (Unknown Source: 1) BeanUtils. InstantiateClass () / / instantiate the instantiation strategy based Bean SimpleInstantiationStrategy. Instantiate () AbstractAutowireCapableBeanFactory. InstantiateBean () / / Perform the Bean instantiation method AbstractAutowireCapableBeanFactory. CreateBeanInstance () AbstractAutowireCapableBeanFactory. DoCreateBean () Develop a / / execution Bean AbstractAutowireCapableBeanFactory createBean () / / the cache without, Call specifying create Bean Bean factory AbstractBeanFactory $1. GetObject () / / from singleton registry access Bean cache DefaultSingletonBeanRegistry. GetSingleton () AbstractBeanFactory. DoGetBean () / / get Bean AbstractBeanFactory. The getBean () / / call the customer class com.tuling.spring.BeanFactoryExample.main()Copy the code

Bean create sequence diagram:

The following points can be summarized from the call procedure:

  1. Calling beanFactory.getBean () triggers an instantiation of the Bean.
  2. DefaultSingletonBeanRegistry cache the singleton beans
  3. The Bean’s creation and initialization is completed by AbstractAutowireCapableBeanFactory.

BeanFactory is different from ApplicationContext

BeanFactory seems to do most things in IOC, so why define an ApplicationContext? ApplicationContext structure

As you can see from the diagram, ApplicationContext is derived from the BeanFactory interface and thus provides all the functionality of the BeanFactory. In addition, the context package provides the following functions:

  1. MessageSource, providing internationalized message access
  2. Resource access, such as URLS and files
  3. Event propagation, a bean that implements the ApplicationListener interface
  4. Load multiple (inherited) contexts so that each focuses on a specific layer, such as the Web layer of the application

The original address

Cbaj. Gitee. IO/blog / 2020/0…