Spring Boot【原理分析】(2)——ApplicationContext

一、类结构图

《Spring Boot【原理分析】(2)——ApplicationContext》

二、初始化refresh

上文中refresh(context); 会执行AbstractApplicationContext.refresh()。
源码:

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

1.invokeBeanFactoryPostProcessors();
有两个BeanFactoryPostProcessor
《Spring Boot【原理分析】(2)——ApplicationContext》
另外,从BeanFactory中获取BeanDefinitionRegistryPostProcessor
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
《Spring Boot【原理分析】(2)——ApplicationContext》
(1)ConfigurationClassPostProcessor先扫描现有bean中的@Configuration 类,如果为空,将不再继续扫描。如果非空,使用ConfigurationClassParser进行解析。
ConfigurationClassParser源码:

protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
        // Recursively process any member (nested) classes first
        processMemberClasses(configClass, sourceClass);

        // Process any @PropertySource annotations
        for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
                sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) {
            if (this.environment instanceof ConfigurableEnvironment) {
                processPropertySource(propertySource);
            }
            else {
                logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
                        "]. Reason: Environment must implement ConfigurableEnvironment");
            }
        }

        // Process any @ComponentScan annotations
        AnnotationAttributes componentScan = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ComponentScan.class);
        if (componentScan != null && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
            // The config class is annotated with @ComponentScan -> perform the scan immediately
            Set<BeanDefinitionHolder> scannedBeanDefinitions =
                    this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
            // Check the set of scanned definitions for any further config classes and parse recursively if necessary
            for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
                if (ConfigurationClassUtils.checkConfigurationClassCandidate(holder.getBeanDefinition(), this.metadataReaderFactory)) {
                    parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
                }
            }
        }

        // Process any @Import annotations
        processImports(configClass, sourceClass, getImports(sourceClass), true);

        // Process any @ImportResource annotations
        if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) {
            AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
            String[] resources = importResource.getAliasedStringArray("locations", ImportResource.class, sourceClass);
            Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
            for (String resource : resources) {
                String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
                configClass.addImportedResource(resolvedResource, readerClass);
            }
        }

        // Process individual @Bean methods
        Set<MethodMetadata> beanMethods = sourceClass.getMetadata().getAnnotatedMethods(Bean.class.getName());
        for (MethodMetadata methodMetadata : beanMethods) {
            configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
        }

        // Process default methods on interfaces
        for (SourceClass ifc : sourceClass.getInterfaces()) {
            beanMethods = ifc.getMetadata().getAnnotatedMethods(Bean.class.getName());
            for (MethodMetadata methodMetadata : beanMethods) {
                if (!methodMetadata.isAbstract()) {
                    // A default method or other concrete method on a Java 8+ interface...
                    configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
                }
            }
        }

        // Process superclass, if any
        if (sourceClass.getMetadata().hasSuperClass()) {
            String superclass = sourceClass.getMetadata().getSuperClassName();
            if (!superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
                this.knownSuperclasses.put(superclass, configClass);
                // Superclass found, return its annotation metadata and recurse
                return sourceClass.getSuperClass();
            }
        }

        // No superclass -> processing is complete
        return null;
    }

ConfigurationClassParser解析过程
1.子类递归
2.@PropertySource
3.ComponentScanAnnotationParser扫描所有@Component (@Configuration,@Controller,@RestController,@ControllerAdvice,@Repository,@Service)类,递归解析这些类。并注册BeanDefinition。
4.@Import
5.@ImportResource
6.@Bean
7.Interface中的@Bean
8.父类循环解析
上述解析的结果都储存在Set<ConfigurationClass>
(2)ConfigurationClassBeanDefinitionReader解析ConfigurationClass转换为BeanDefinition,包括自身,BeanMethod,@ImportResource,@Import。
XmlBeanDefinitionReader解析@ImportResource的xml文件。并注册BeanDefinition

2.finishBeanFactoryInitialization(beanFactory);
实例化所有bean
构造完一个bean后,会用AutowiredAnnotationBeanPostProcessor检查所有@Autowired依赖属性,并构建相应的bean。
bean装载过程:
1. 实例化;
2. 设置属性值;(包括依赖注入)
3. 如果实现BeanNameAware接口,调用setBeanName设置Bean的ID或者Name;
4. 如果实现BeanClassLoaderAware接口,调用setBeanClassLoader设置ClassLoader;
5. 如果实现BeanFactoryAware接口,调用setBeanFactory 设置BeanFactory;
6. 如果实现ApplicationContextAware,调用setApplicationContext设置ApplicationContext
7. 调用BeanPostProcessor的预先初始化方法(包含@PostConstruct);
8. 调用InitializingBean的afterPropertiesSet()方法;
9. 调用定制init-method方法;
10. 调用BeanPostProcessor的后初始化方法;AOP代理类通过AspectJAwareAdvisorAutoProxyCreator生成。
初始化bean源码:

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                invokeAwareMethods(beanName, bean);
                return null;
            }
        }, getAccessControlContext());
    }
    else {
        // Aware接口调用 
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 调用BeanPostProcessor.postProcessBeforeInitialization()
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 调用InitializingBean.afterPropertiesSet()
        // 调用自定义init-method
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null),
                beanName, "Invocation of init method failed", ex);
    }

    if (mbd == null || !mbd.isSynthetic()) {
        // 调用BeanPostProcessor.postProcessAfterInitialization()
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}

3.finishRefresh();

调用Lifecycle.start(),更加依赖递归调用start依赖的bean。

    原文作者:Spring Boot
    原文地址: https://blog.csdn.net/wwmfeng/article/details/53467279
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞