Start Load Initialization Process of Spring Bean Container

1. DESC

Spring's handling of beanFactory

2. CODE

public void refresh() 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();
        }
    }
}

3. RUSH from top to bottom

3.1 prepareRefresh()

Here you don't need to look at the configuration and parameter checking of your own.

3.2 obtainFreshBeanFactory()

  1. Loading NameSpacehandler
  2. Generate Beandifinitions using each NameSpcaceHandler and register them in beanfactory

3.2.1 Load NameSpace Handler

  1. The parsing of the NameSpaceHandler loading process has been written and is no longer written; see the previous article

3.2.2 NameSpaceHandler handles the definition of the generated bean (note that only the generated bean Definition is generated, not the specific bean, and the relevant Class file is not loaded)

  1. NamespaceHandlerSupport
//It's no use returning. It should be defined as void. The registry of parserContext is bean Factory.
public BeanDefinition parse(Element element, ParserContext parserContext) {
    //Get specific Bean Definition Parsers, such as ComponentScanBean Definition Parser
    return findParserForElement(element, parserContext).parse(element, parserContext);
}
  1. ComponentScanBean Definition Parser is a sample example, you can see what's going on.
public BeanDefinition parse(Element element, ParserContext parserContext) {
    String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);//Get the package name set by basepackage
    basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);//Possible use$
    String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);//Resolve all package s
    // Actually scan for bean definitions and register them.
    ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);//Configure Scanner
    Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);//Sweep bag
    registerComponents(parserContext.getReaderContext(), beanDefinitions, element);//Register with bean Factory
    return null;
}

3.3 prepareBeanFactory(beanFactory)

Mainly completing the initialization of BeanFactoryPost Processors

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	...
	 //Note that this is LTW, load time code weaving to enhance AOP
	if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
	}
	...
}

3.4 invokeBeanFactoryPostProcessors(beanFactory) executes BeanFactoryPostProcessors,

Start the process for BeanFactory

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); //Notice that AspectJWeaving Enabler is a special class designed to enable ClassLoader-level Op, which is somewhat similar to Instrument In Jvm in the past.
	// Check for LTW support.
	if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}
}

3.5 The following methods feel like they need not be written.

It's what bean s are initially like.

Actually, I want to grab the Transactional implementation code; (This is a bit unclear and how JVM redifineClass replaces the method stack for the active stack frame)

But I'm really not familiar with AspectJ, so let's give it up first. I'll go back and add it when I click on the ApsectJ technology tree.

4. Summarize the overall process

ContextLoaderListener initialization

New DefaultListable BeanFactory () Creates bean Factroy

New XmlBean Definition Reader (beanFactory) creates parsers

new BeanDefinitionDocumentReader

Load the configuration file applicationContext.xml

Namespace Handler is determined and initialized according to the namespace of tag in the configuration file and / META-INF/spring.handlers of all jar s under lib

BeanDefinition Parser () is determined according to the specific value of tag; ParserContext ParserContext is called to complete the registration of BeanDefinition, and the registry of parserContext is the beanFactory that was first created;

postProcessBeanFactory () completes the initialization of various beanFatoryPostProcessor s

Perform these beans FatoryPostProcessor note that AspectJWeaving Enabler, which has a special genus, is the core logic responsible for enabling ClassLoader-level Aop (i.e., injecting ClassFileTransformer into ClassLoader)

Then there's the bean's various loading logic... no writing.

Tags: Spring jvm xml

Posted on Thu, 08 Aug 2019 04:55:50 -0700 by Tjorriemorrie