introduce

The whole IOC process is roughly divided into the following steps:

  • The IOC container the entrance is AbstractApplicationContext# refresh
  • Parse to Resource objects via ResourceLoader (where Spring abstracts all resources as resources)
  • Create a default Bean registry DefaultListableBeanFactory
  • BeanDefinitionReader is mainly for parsing and registration of beans
  • XmlBeanDefinitionReader uses it to parse bean definitions in AN XML configuration, delegating BeanDefinition
  • BeanDefinitionRegistry saves beanDefinitions to ConcurrentHashMap

Detailed instructions

ContextLoaderListener implements the ServletContextListener interface. When the web.xml listener is configured and the container is started, the method implemented by default is executed. The ContextLoaderListener inherits the ContextLoader, so the whole loading and configuration process is done by the ContextLoader.

In the web container startup will call contextInitialized method, contextInitialized actual call ContextLoader# initWebApplicationContext method, the initWebApplicationCo What ntext does:

  • CreateWebApplicationContext, initialize XmlWebApplicationContext
  • Register ApplicationContext with the current servletContext
  • Finally, XmlWebApplicationContext#refresh() refreshes the entire container

The flow chart of the refresh

instructions

-> prepareRefresh() -- -> ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); - > AbstractRefreshableApplicationContext# refreshBeanFactory - > createBeanFactory () - > create The default implementation DefaultListableBeanFactory (ListableBeanFactory and BeanDefinitionRegistry interface: A bean definition object based mature bean bean factory factory) - > configuration - > loadBeanDefinitions - > subclass AbstractXmlApplicationContext# loadBeanDefinitions - > new XmlBeanDefinitionReader(); Create beanDefault reader -> Set environment -> Define resourceLoader -> Leave entry for subclasses to initialize beanDefinition reader -> loadBeanDefinitions Load bean loadBeanDefinitions(XmlBeanDefinitionReader reader) -> AbstractBeanDefinitionReader#loadBeanDefinitions(reader Load Bean according to configuration file) -> getResourceLoader() -> XmlBeanDefinitionReader#loadBeanDefinitions(read from configuration file) -> XmlBeanDefinitionReader#doLoadBeanDefinitions ->doLoadDocument ->DefaultDocumentLoader#loadDocument -> DefaultDocumentLoader# createDocumentBuilderFactory - > DocumentBuilder builder = createDocumentBuilder - > builder to parse the XML file - > registerBeanDefinitions - > DefaultBeanDefinitionDocumentReader = createBeanDefinitionDocumentReader - > get has the number of registered bean - > createReaderContext -> DefaultBeanDefinitionDocumentReader# ->doRegisterBeanDefinitions -> createDelegate -> BeanDefinitionParserDelegate - > preProcessXml processing before (to subclass implementation) - > parseBeanDefinitions - > ParseDefaultElement -> processBeanDefinition -> parseDefaultElement -> processBeanDefinition -> BeanDefinitionParserDelegate to parse the XML for BeanDefinitionHolder - > decorateBeanDefinitionIfRequired decorate the bean depends on the subclass - > BeanDefinitionReaderUtils. RegisterBeanDefinition to beanDefinition DefaultListableBeanFactory registration To save beanDefinition to DefaultListableBeanFactory# beanDefinitionMap - > fireComponentRegistered send register event - > BeanDefinitionParserDelegate# parseCustomElement - here is the handle inheritance NamespaceHandler interface, It's essentially spring custom tag parsing -> postProcessXml processing (left to subclass implementation) -> prepareBeanFactory() configuring the factory's standard context characteristics - ClassLoader and post-processor as shown above - > the beanFactory. SetBeanClassLoader - > setBeanExpressionResolver set expression editor - > addPropertyEditorRegistrar Create a new ResourceEditorRegistrar -> addBeanPostProcessor bean factory for the given ResourceLoader and PropertyResolver Because we often implement some kind of spring callback - > ApplicationContextAwareProcessor, to achieve the function of the Processor is Aware the bean calls the Aware of the interface method of defining interfaces, And into the corresponding parameters - > ignoreDependencyInterface set some ignore interface - > registerResolvableDependency - > addBeanPostProcessor why there is another, Why don't we put together - > ApplicationListenerDetector - > setTempClassLoader - > registerSingleton - > addBeanPostProcessor (new LoadTimeWeaverAwareProcessor(beanFactory) -> setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())) -> registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()) -> registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()) -> registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()) ->postProcessBeanFactory() -> addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig)) -> ignoreDependencyInterface(ServletContextAware.class) -> ignoreDependencyInterface(ServletConfigAware.class) -> WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext); -> WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig); - > invokeBeanFactoryPostProcessors (instantiate and call all registered spring BeanFactoryPostProcessor bean, if given, consider explicit order.) Must call - > before the singleton instantiation registerBeanPostProcessors key - > initMessageSource () - > onRefresh () - > registerListeners () - > finishBeanFactoryInitialization(beanFactory) -> finishRefresh()Copy the code

component

Resource

  1. Spring calls all kinds of files resources, but for Spring developers, resources are mostly XML files.
  2. The Resource interface is an abstraction of a concrete Resource access policy and is implemented by all Resource access classes. The Resource interface itself does not provide implementation logic for accessing any of the underlying resources. Spring will provide different Resource implementation classes for different underlying resources, and each implementation class is responsible for different Resource access logic.

ResourceLoader

The literal is the loader for Resource data

PathMatchingResourcePatternResolver

Returns where the resource loader is used for the resource. The ResourcePatternResolver interface can be examined and transformed to load multiple resources for a given resource pattern

BeanFactoryPostProcessor

The extension point left for the user can be modified to add a BeanDefinition. Because at this point all beanDefinitions have been loaded, but no beans have been created. This is typically used when you need to override or replace a Bean’s properties. This extension point provides two methods:

BeanPostProcessor

Is called after the Bean is newly created but before it is initialized. For example, before afterPropertiesSet of an InitializingBean, or before a custom init-method. In Bean after initialization, postProcessAfterInitialization call methods.

ApplicationContext

ApplicationContext enrichis the functionality of the BeanFactory by inheriting the following classes

  1. EnvironmentCapable,
  2. ListableBeanFactory,
  3. HierarchicalBeanFactory,
  4. MessageSource,
  5. ApplicationEventPublisher,
  6. ResourcePatternResolver

AbstractApplicationContext ConfigurableApplicationContext is realized

Note: ConfigurableApplicationContext implements the ApplicationContext, Lifecycle, Closeable AbstractApplicationContext this class is too much work, the core core, As a side note, a lot of spring logic is put into abstract classes. When you look at the code and you can’t find the call relationship, you can look in the parent class

ClassPathXmlApplicationContext

ClassPathXmlApplicationContext inside the constructor to do something It calls the AbstractApplicationContext refresh () method

BeanDefinitionReader

BeanDefinitionReader does not load configuration files directly. If you need to encapsulate the configuration file as a Resource, convert the Resource into various work points of BeanDefinition before calling loadBeanDefinitions()

BeanDefinitionReader is simply a standard bean Definition reader interface, which provides several standard methods:

  1. BeanDefinitionRegistry getRegistry();
  2. ResourceLoader getResourceLoader();
  3. ClassLoader getBeanClassLoader();
  4. BeanNameGenerator getBeanNameGenerator();
  5. int loadBeanDefinitions(Resource resource)

LoadBeanDefinitions has several overloaded methods, but they all do the same thing: load the bean definition

First is getRegistry is used to obtain a bean registered container classes, BeanDefinitionRegistry here is an interface that will mention DefaultListableBeanFactory specific to the class,

DefaultListableBeanFactory

Is the core part of the bean loading, it is spring registration and load the default implementation of bean DefaultListableBeanFactory inherited AbstractAutowireCapableBeanFactory, And has realized the ConfigurableListableBeanFactory, BeanDefinitionRegistry interface

XmlWebApplicationContext

/ / by XmlBeanDefinitionReader load bean definition loadBeanDefinitions (DefaultListableBeanFactory the beanFactory)

BeanDefinitionRegistry

Purpose: Interface used to hold the registry of bean definitions, such as RootBeanDefinition and ChildBeanDefinition instances. It is typically implemented by BeanFactories that use AbstractBeanDefinition hierarchies internally. This is the only interface in Spring’s Bean factory package that encapsulates the bean definition registry. The standard BeanFactory interface only covers access to a fully configured factory instance

DocumentLoader

Defines the capability to load from a resource file into a Document

BeanDefinitionDocumentReader

Implements BeanDefinitionDocumentReader interface, DefaultBeanDefinitionDocumentReader is not responsible for any specific bean, it is geared to the needs of the XML Document object, according to its element namespace and name, Act like a routing (namespace judgment, however, is entrusted to the delegate to do), and it cooperate with BeanDefinitionParserDelegate, the parsing task handover BeanDefinitionParserDelegate to do it

BeanDefinitionParserDelegate

Complete parsing of specific beans (e.g.,, tags). Extended tags are referred to different NamespaceHandler and BeanDefinitionParser

BeanDefinitionParser

Parse configuration files into beanDefinitions (context: Component-scan, AOP :config, etc. Tags are different BeanDefinitionParser tags), usually used in NamespaceHandler. Spring also provides a lot of support for custom BeanDefinitionParser, with a few abstract classes adding a little functionality to meet most of your needs.

NamespaceHandler

To parse a custom bean, you do so through your own NamespaceHandler. Defines the http://www.springframework.org/schema/osgi=org.springframework.osgi.config.OsgiNamespaceHandler, for example, so when touched the osgi scheme OsgiNamespaceHandler is called to parse; For common extension requirements, simply have your own Handler inherit NamespaceHandlerSupport and implement the init() method. For special extension requirements, you can implement your own NamespaceHandler.

conclusion

  • Spring’s code structure is very clear
  • The responsibilities of each class are very simple, and we try to write the code so that each class does only one thing
  • We can do some framework level stuff with BeanPostProcessor