SpringBoot 启动流程

2 篇文章 0 订阅

1. 启动入口

首先从 SpringBoot 启动流程进去

public class MyApplicationContext {

    public static void main(String[] args) {
		// 启动方法入口
        SpringApplication.run(MyApplicationContext.class, args);
    }
}

2. 创建 SpringApplication

public class MyApplicationContext {
	// 创建 SpringApplication
	public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
        
		return run(new Class<?>[] { primarySource }, args);
	}
}    

3. 运行 Spring 应用程序

public class SpringApplication {
    
    // 运行 spring 应用程序
    public ConfigurableApplicationContext run(String... args) {
        // 记录启动时间
        long startTime = System.nanoTime();
        // spring应用上下文,也就是我们所说的spring根容器
        DefaultBootstrapContext bootstrapContext = createBootstrapContext();
        
        ConfigurableApplicationContext context = null;
        // 设置jdk系统属性java.awt.headless,默认情况为true即开启
        configureHeadlessProperty();
        // 获取启动时监听器(EventPublishingRunListener实例)
        SpringApplicationRunListeners listeners = getRunListeners(args);
        // 触发ApplicationStartingEvent事件,启动监听器会被调用,一共5个监听器被调用,但只有两个监听器在此时做了事
        listeners.starting(bootstrapContext, this.mainApplicationClass);
        try {
            // 参数封装,也就是在命令行下启动应用带的参数,如--server.port=9000
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            // 准备环境:1、加载外部化配置的资源到environment;2、触发ApplicationEnvironmentPreparedEvent事件
            ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
            // 配置spring.beaninfo.ignore,并添加到名叫systemProperties的PropertySource中;默认为true即开启
            configureIgnoreBeanInfo(environment);
            // 打印banner图
            Banner printedBanner = printBanner(environment);
            
             <!-- 创建应用上下文,这是本文重点 -->
            context = createApplicationContext();
            context.setApplicationStartup(this.applicationStartup);
            // 装配应用上下文
            prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
            <!-- 刷新应用上下文:解析配置文件,加载业务 `bean`,启动 `tomcat` 等 -->
            refreshContext(context);
            afterRefresh(context, applicationArguments);
            Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
            }
            listeners.started(context, timeTakenToStartup);
            callRunners(context, applicationArguments);
        } catch (Throwable ex) {
            handleRunFailure(context, ex, listeners);
            throw new IllegalStateException(ex);
        }
        try {
            Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
            listeners.ready(context, timeTakenToReady);
        } catch (Throwable ex) {
            handleRunFailure(context, ex, null);
            throw new IllegalStateException(ex);
        }
        return context;
    }
}

3.1 创建应用上下文

public interface ApplicationContextFactory {
    
    ApplicationContextFactory DEFAULT = (webApplicationType) -> {
        try {
            switch (webApplicationType) {
                case SERVLET:
                    return new AnnotationConfigServletWebServerApplicationContext();
                case REACTIVE:
                    return new AnnotationConfigReactiveWebServerApplicationContext();
                default:
                    return new AnnotationConfigApplicationContext();
            }
        }
        catch (Exception ex) {
            throw new IllegalStateException("Unable create a default ApplicationContext instance, "
                    + "you may need a custom ApplicationContextFactory", ex);
        }
    };
}

根据 SpringApplication 的 webApplicationType 来实例化对应的上下文;如果 webApplicationType 的值是

  • SERVLET:那么实例化 AnnotationConfigServletWebServerApplicationContext (web应用)
  • REACTIVE:实例化 AnnotationConfigReactiveWebServerApplicationContext(响应式编程),
  • 默认情况:(也就是我们所说的非web应用),实例化 AnnotationConfigApplicationContext。

3.2 刷新应用上下文

public class SpringApplication {
    
    private void refreshContext(ConfigurableApplicationContext context) {
        if (this.registerShutdownHook) {
            shutdownHook.registerApplicationContext(context);
        }
        // 核心方法
        refresh(context);
    }
}

refresh(context) ——> ServletWebServerApplicationContext.refresh()

public class ServletWebServerApplicationContext {

    public final void refresh() throws BeansException, IllegalStateException {
        try {
            super.refresh();
        }
        catch (RuntimeException ex) {
            WebServer webServer = this.webServer;
            if (webServer != null) {
                webServer.stop();
            }
            throw ex;
        }
    }
}

ServletWebServerApplicationContext.refresh() ——> AbstractApplicationContext.refresh()

public class AbstractApplicationContext {

    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

            // 初始化一些配置属性,验证配置文件
            prepareRefresh();

            // 简单的获取 beanFactory
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // 装配 beanFactory
            prepareBeanFactory(beanFactory);

            try {
                // 允许在上下文的子类中对bean factory进行后处理
                postProcessBeanFactory(beanFactory);

                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                <!-- 3.2.1 解析配置文件、生成所有的beanDefinitions -->
                invokeBeanFactoryPostProcessors(beanFactory);

                // 分类、排序、注册(注入)所有的BeanPostProcessors,用于处理 bean 的初始化流程
                registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();

                // 国际化
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // 主要创建并初始化容器
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                 <!-- 3.2.2 主要是初始化非懒加载单例 -->
                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();
                contextRefresh.end();
            }
        }
    }
}
3.2.1 解析配置文件、生成所有的 beanDefinitions
3.2.1.1 什么是BeanDefinition?

简单来说就是对 Bean 信息的定义。

描述一个 Bean 的全部信息,class对象、Bean作用域(scope)、是否懒加载(lazyInit)等。

spring 中每一个被扫描到的 bean 都会生成一个 BeanDefinition,后续 spring 根据 BeanDefinition 实例化生成 Bean 实例,BeanDefinition 定义信息差异也会导致实例化流程差异。

3.2.1.2 invokeBeanFactoryPostProcessors 解读
final class PostProcessorRegistrationDelegate {

    public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        
        Set<String> processedBeans = new HashSet<>();

        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                }
                else {
                    regularPostProcessors.add(postProcessor);
                }
            }

            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
            currentRegistryProcessors.clear();

            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
            currentRegistryProcessors.clear();

            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    if (!processedBeans.contains(ppName)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                <!-- 3.2.1.2.1 解析配置类,生成 beanDefinitions -->
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
                currentRegistryProcessors.clear();
            }

            <!-- 3.2.1.2.2 调用到目前为止处理的所有处理器的 postProcessBeanFactory 回调方法
                自定义 BeanFactoryPostProcessor 的回调方法会在这调用 -->
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
            
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            if (processedBeans.contains(ppName)) {

            }
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        beanFactory.clearMetadataCache();
    }

}
a. BeanFactoryPostProcessor扩展
public interface BeanFactoryPostProcessor {

	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

在 BeanDefinitions 生成之后,BeanDefinitions 生成Bean实例之前,会调用 BeanFactoryPostProcessor.postProcessBeanFactory() 方法。我们可以自定义类实现BeanFactoryPostProcessor 重写方法来达到修改任意 BeanDefinition 信息的效果

3.2.1.2.1 ConfigurationClassPostProcessor 解析配置类,生成 beanDefinitions

invokeBeanDefinitionRegistryPostProcessors() ——> ConfigurationClassPostProcessor.processConfigBeanDefinitions()

public class ConfigurationClassPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
        int registryId = System.identityHashCode(registry);
        if (this.registriesPostProcessed.contains(registryId)) {
            throw new IllegalStateException(
                    "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
        }
        if (this.factoriesPostProcessed.contains(registryId)) {
            throw new IllegalStateException(
                    "postProcessBeanFactory already called on this post-processor against " + registry);
        }
        this.registriesPostProcessed.add(registryId);
		<!--核心处理方法-->
        processConfigBeanDefinitions(registry);
    }
}
  • ConfigurationClassPostProcessor:这个类就是专门解析配置类的类。它实现了 BeanDefinitionRegistryPostProcessor 接口,它会解析会加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解。
public class ConfigurationClassPostProcessor {

    public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
        
        ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);
        ......
     	// 这个方法来对主类上的注解进行解析
    	parser.parse(candidates);
        
        Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
        // 解析后的 configClasses 加载为 BeanDefinitions
        this.reader.loadBeanDefinitions(configClasses);
     	......
    }
}
3.2.1.2.2 解析常规业务类 ConfigurationClassParser
  • 如果类被 Conditional 注解,且 matches 方法不匹配,则不解析这个类,跳过
  • 递归解析类中的内部类
  • 解析 @PropertySources
  • 解析 @ComponentScan/s,@ComponentScan
  • 解析 @Import
  • 解析 @ImportResource
  • 解析 @Bean
  • 解析 类接口类中的 @Bean
public class ConfigurationClassParser {

    //ConfigurationClassParser:a 中的 this.parse(...),最后走到这里
    protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
        //如果类被Conditional注解(conditionOnClass 等),且matches方法不匹配,则不解析这个类,跳过,注意:这里并不处理 ConditionOnBean/MissingBean 注解,这要到全部解析完后,在 loadBedifinition 中再做判断
        //这个if一直到最后
        if (!this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
            //将configclass包装成SourceClass
            ConfigurationClassParser.SourceClass sourceClass = this.asSourceClass(configClass);
            //递归调用进行解析
            do {
                sourceClass = this.doProcessConfigurationClass(configClass, sourceClass);
            } while(sourceClass != null);
            this.configurationClasses.put(configClass, configClass);
        }
    }

    //ConfigurationClassParser
    protected final ConfigurationClassParser.SourceClass doProcessConfigurationClass(ConfigurationClass configClass, ConfigurationClassParser.SourceClass sourceClass) throws IOException {
        if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
            //递归解析类中的内部类
            this.processMemberClasses(configClass, sourceClass);
        }

        // 查找该类有没有@PropertySources注解,有的话做处理
        // 查找该参数在类及其父类找中对应的注解
        Iterator var3 = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class, PropertySource.class).iterator();
        AnnotationAttributes importResource;
        while(var3.hasNext()) {
            importResource = (AnnotationAttributes)var3.next();
            
            <!-- a.1.1 处理@PropertySources注解 -->
            this.processPropertySource(importResource);
        }

        //处理@ComponentScan/s,@ComponentScan
        Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
        if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
            Iterator var13 = componentScans.iterator();

            while(var13.hasNext()) {
                AnnotationAttributes componentScan = (AnnotationAttributes)var13.next();
                
                <!--a.1.2 解析 @ComponentScan/s,@ComponentScan 得到路径下的类-->
                Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
                Iterator var7 = scannedBeanDefinitions.iterator();
                while(var7.hasNext()) {
                    //递归解析扫描出来的类:回到a.1进行解析
                    this.parse(bdCand.getBeanClassName(), holder.getBeanName());
                }
            }
        }

        <!--a.1.3 处理Import注解,其中getImports():递归得到了目标类的所有import-->
        this.processImports(configClass, sourceClass, this.getImports(sourceClass), true);

        //处理@ImportResource:@ImportResource(“classpath:config.xml”),加入当前类的ImportedResource中,留待以后处理
        importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
        if (importResource != null) {
            // 遍历配置的locations,加入到configClass 中的ImportedResource
            String[] resources = importResource.getStringArray("locations");
            Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
            for(int var22 = 0; var22 < var21; ++var22) {
                String resource = var19[var22];
                String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
                configClass.addImportedResource(resolvedResource, readerClass);
            }
        }

        //处理@Bean注解:获取类内部被@Bean注解修饰的方法,然后添加到配置类的beanMethods属性中,这里并没有处理 conditional 注解
        
        <!--a.1.4 解析 @Bean 注解,得到注解方法,加入目标类属性中-->
        Set<MethodMetadata> beanMethods = this.retrieveBeanMethodMetadata(sourceClass);
        Iterator var17 = beanMethods.iterator();
        while(var17.hasNext()) {
            MethodMetadata methodMetadata = (MethodMetadata)var17.next();
            configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
        }
        //处理类实现接口的类被@Bean注解的方法
        this.processInterfaces(configClass, sourceClass);

        //如果有父类的话,则返回父类进行进一步的解析
        if (sourceClass.getMetadata().hasSuperClass()) {
            String superclass = sourceClass.getMetadata().getSuperClassName();
            if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
                this.knownSuperclasses.put(superclass, configClass);
                return sourceClass.getSuperClass();//return不为null,则不跳过最外层的循环,继续解析父类!
            }
        }
        return null;//走到这里,才跳过外层循环
    }

}
3.2.2 BeadDefinition 转化为 Bean 的过程(IOC)

finishBeanFactoryInitialization(),是整个 Spring IoC 核心中的核心,该方法会实例化所有剩余的非懒加载单例 bean

public class AbstractApplicationContext {
    
    // 完成此上下文bean工厂的初始化,初始化所有剩余的单例bean。
    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        
        // 初始化此上下文的转换服务
        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
            beanFactory.setConversionService(
                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
        }

        // 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }

        // 初始化LoadTimeWeaverAware Bean实例对象
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

        // 停止使用临时的类加载器
        beanFactory.setTempClassLoader(null);

        // 冻结所有bean定义,注册的bean定义不期望被修改
        beanFactory.freezeConfiguration();

        <!--3.2.2.1 实例化所有剩余(非懒加载)单例对象-->
        beanFactory.preInstantiateSingletons();
    }
}

3.2.2.1 实例化所有剩余(非懒加载)单例对象

DefaultListableBeanFactory.preInstantiateSingletons

public class DefaultListableBeanFactory {
    
    public void preInstantiateSingletons() throws BeansException {
        if (logger.isDebugEnabled()) {
            logger.debug("Pre-instantiating singletons in " + this);
        }

        // 创建 beanDefinition 的副本 beanNames 用于后续的遍历,以允许init等方法注册新的bean定义
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        // 遍历 beanNames,触发所有非懒加载单例 bean 的初始化
        for (String beanName : beanNames) {
            // 获取 root beanDefinition
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                // bd对应的Bean属性:不是抽象类 && 单例 && 不是懒加载
                
                if (isFactoryBean(beanName)) {
                    // 判断beanName对应的bean是否实现了FactoryBean
                    
                    // 通过 beanName 获取 FactoryBean 实例      
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                            ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                         // 判断是否需要急切实例化,默认为false。可通过实现SmartFactoryBean的isEagerInit方法修改
                        if (isEagerInit) {
                            
                            // 实例化 BeanFacotry 的 getObject()方法生成的对象
                            getBean(beanName);
                        }
                    }
                }
                else {
                    
                    <!-- 根据beanName实例化bean -->
                    getBean(beanName);
                }
            }
        }

        // 遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
        for (String beanName : beanNames) {
            Object singletonInstance = getSingleton(beanName);
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }
}
3.2.2.2 根据 BeanName 获取 Bean OR 生成 Bean

它会调用doGetBean方法,在spring源码中,do前缀的方法一般都是比较重要的方法

public class AbstractBeanFactory {
    
    @Override
    public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null, false);
    }
}
a. AbstractBeanFactory.doGetBean()
public class AbstractBeanFactory {
    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
                              @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

        // 将 name 真正解析成真正的 beanName,主要是去掉 FactoryBean 里的 “&” 前缀,和解析别名。
        final String beanName = transformedBeanName(name);
        Object bean;

        <!--b.核心方法,根据 BeanName 从缓存中获取实例 -->
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            //......省略打印日志
            
            /*
              1.如果 Bean实例不为空进入这里
              2.如果这个Bean实例是 FactoryBean ,这里会调用它的 getObject()方法,创建自定义对象。
            */
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

       	else {
            
            // 根据BeanName判断 Bean是否正在创建中
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // 检查bean的定义信息是否已经存在与这个工厂
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // 因为没有ParentBeanFactory,所以不会进入if判断
                String nameToLookup = originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                }
                else if (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }

            if (!typeCheckOnly) {
                // 将这个 beanName 标识为已经创建状态
                markBeanAsCreated(beanName);
            }

            try {
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);

                // 保证当前bean所依赖的bean的初始化。
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    
                    /*
                     * 因为此处没有依赖其它的 bean,所以不会进入if判断,如果有依赖其它的 bean,且这些 bean还没有初始化,则
                     * 会调用 registerDependentBean(dep, beanName);初始化依赖的 bean
                     */
                    for (String dep : dependsOn) {
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        registerDependentBean(dep, beanName);
                        try {
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException();
                        }
                    }
                }

                // 创建bean实例
                if (mbd.isSingleton()) {
                    
                     <!--c.核心方法,根据 getSingleton 从缓存中获取实例,跟上面的 getSingleton 是重载关系 -->
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            <!--d.核心方法,创建Bean实例 -->
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            //......一些异常的校验
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                else if (mbd.isPrototype()) {
                    // It's a prototype -> create a new instance.
                    Object prototypeInstance = null;
                    try {
                        beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }
                else {
                    String scopeName = mbd.getScope();
                    final Scope scope = this.scopes.get(scopeName);
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                    }
                    try {
                        Object scopedInstance = scope.get(beanName, () -> {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                afterPrototypeCreation(beanName);
                            }
                        });
                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    }
                    catch (IllegalStateException ex) {
                        //......一些异常的校验
                    }
                }
            }
            catch (BeansException ex) {
                //......一些异常的校验
            }
        }

        // Check if required type matches the type of the actual bean instance.
        if (requiredType != null && !requiredType.isInstance(bean)) {
            try {
                T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                if (convertedBean == null) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
                return convertedBean;
            }
            catch (TypeMismatchException ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }

}
b. 三级缓存类 DefaultSingletonBeanRegistry

DefaultSingletonBeanRegistry 是 spring 的容器,它有三级缓存

  • 一级缓存:beanName——>完整bean实例
  • 二级缓存:beanName——>提交曝光半成品bean实例
  • 三级缓存:beanName——>ObjectFactory(提供生成Bean的工厂)
b.1 二级缓存解决了什么问题

解决B、C对同一个类A循环依赖,产生多个代理A对象问题 (earlySingletonObjects)

b.2 三级缓存解决了什么问题

解决循环依赖的问题。

b.3 两个重载的 getSingleton()

第一个getSingleton()

public class DefaultSingletonBeanRegistry {
    
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // 从一级缓存里面获取bean实例
        Object singletonObject = this.singletonObjects.get(beanName);
        
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            // 一级缓存中不存在 && 这个bean正在被创建进入这里
            
            /*
             * 什么情况下会进入这里?例子:A实例还没创建完,但是标记了正在创建,这时调用 populateBean()方法发现需要注入属性B,
             * 当B实例在创建过程中,发现需要实例A,调用这个方法,判断A不在一级缓存,但是被标识了正在创建中
             */
            synchronized (this.singletonObjects) {
                
                // 从二级缓存中获取bean实例
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    // 二级缓存中也不存在,根据allowEarlyReference判断是否应该从三级缓存中
                    
                    // 从三级缓存获取 ObjectFactory,用来创建Bean
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        
                        // 三级缓存创建的Bean添加进二级缓存
                        this.earlySingletonObjects.put(beanName, singletonObject);
                         // 三级缓存删除这个beanName数据
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }

}

主要是从IOC缓存中获取Bean实例,如果是普通场景,则直接从一级缓存中获取Bean实例,没有则返回null。如果当前Bean正在创建中,则会去二级缓存、三级缓存中获取Bean。

这里有问题问题,Bean正在创建中为什么会进入这里?答:发生了循环依赖问题?

A在实例化完之前会调用populateBean方法进行属性注入,当发现需要注入B时会去创建B实例,当B在实例化完之前发现也要注入A,这时它调用getSingleton这个方法。因为A还没实例化完,所有一级缓存是没有完整的A实例的,然后判断A正在创建中去二级、三级缓存中拿,A在调用populateBean注入B实例之前,会把创建A实例的工厂放入三级缓存。然后B调用工厂方法,拿取A的实例完成注入。(B注入的A实例可能是原始的A实例 or 代理后的A实例,这个后面会分析)

第二个getSingleton()

public class A {
    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized (this.singletonObjects) {
             // 从一级缓存获取bean实例
            Object singletonObject = this.singletonObjects.get(beanName);
            
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    //...... 一些异常的校验
                }
              
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    // 调用 ObjectFactory 的实例的getObject()方法,创建bean实例
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) {
                     //...... 一些异常的校验
                }
                catch (BeanCreationException ex) {
                    //...... 一些异常的校验
                }
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    // 将Bean实例添加到一级缓存,删除二级缓存、三级缓存数据
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }
}
c. 创建Bean流程
public class DefaultSingletonBeanRegistry {
    
    @Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {

        // 省略日志处理
        RootBeanDefinition mbdToUse = mbd;

       
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        // Prepare method overrides.
        try {
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            //......抛出异常
        }

        try {
            /*
             * c.1
             * 执行InstantiationAwaeBeanPostProcessor.postProcessBeforeInstantiation方法,
             * 它是个接口,继承了BeanPostProcessor。我们可以实现它,来实现这段逻辑
            */
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            //......抛出异常
        }

        try {
            // 真正创建单例bean方法
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isDebugEnabled()) {
                logger.debug("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
            //......抛出异常
        }
        catch (Throwable ex) {
            //......抛出异常
        }
    }

}
c.1 InstantiationAwaeBeanPostProcessor扩展

为了扩展性,spring 提供了在 Bean实例化之前,给一次修改返回特定Bean 的机会,如果返回了Bean,则不用继续往下执行走spring常规Bean生命周期流程。使用方式只要实现 InstantiationAwaeBeanPostProcessor,重写postProcessBeforeInstantiation() 方法逻辑。

示例:

@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanName.equals("myService")) {
            return new MyBean();
        }
        return null;
    }
}

自定义 MyBeanPostProcessor 实现 InstantiationAwareBeanPostProcessor, 它会加入 BeanPostProcessor 集合中,这样就可以在 beanName 为 myService 的 Bean 实例化之前,返回我们指定的 Bean 实例,它将直接加入到 IOC 一级缓存中,后面则不会执行 spring常规 Bean 生命周期创建这个 Bean实例,从而达到修改 Bean 实例的效果。

d. doCreateBean流程
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {
    
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {

        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;
        
        // 如果定义的是单例模式,就先从缓存中清除
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        // 如果instanceWrapper为空,就对bean进行实例化
        if (instanceWrapper == null) {
            // 创建了bean实例返回的是个包装类
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        // 获取bean实例
        final Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
             // 解析目标类型 = beanClass对象
            mbd.resolvedTargetType = beanType;
        }

        // // 使用后置处理器 对其进行处理
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    
                    /*
                     * 这里主要是 MergedBeanDefinitionPostProcessor
                     * 对@Autowire,@Value等这些注解进行处理, 相关的可以
                     * 参考AutowiredAnnotationBeanPostProcessor相关逻辑
                     */
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                     //.......省略 抛出异常
                }
                mbd.postProcessed = true;
            }
        }

        /*
         * 是否需要提前曝光: 单例 && 允许循环依赖 && 当前bean正在创建中
         * 这里主要是调用 方法addSingletonFactory ,往三级缓存放入一个 ObjectFactory 实现类。
         * 当调用三级缓存中ObjectFactory实现类创建Bean时,主要调用了SmartInstantiationAwareBeanPostProcessor,
         * 的getEarlyBeanReference()方法,获取到的可能是bean实例本身,也可能是AOP代理对象
         */
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            //......省略debug日志
             <!-- getEarlyBeanReference() 核心方法,获取提交暴露的Bean-->
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            
            // 对bean进行填充,将各个属性值注入,其中可能存在依赖于其他bean的属性,会递归初始化
            populateBean(beanName, mbd, instanceWrapper);
            
            /* 
             * 进一步初始化Bean
             * 调用后置处理器 BeanPostProcessor 里面的postProcessBeforeInitialization()方法
             * 调用 initialzingBean,调用实现的 afterPropertiesSet()方法
             * 调用 init-mothod,调用相应的init()方法    
             * 调用后置处理器 BeanPostProcessor 里面的调用实现的postProcessAfterInitialization()方法
             */
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
        catch (Throwable ex) {
            //.......省略 抛出异常
        }

        if (earlySingletonExposure) {
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                }
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        //.......省略 抛出异常
                    }
                }
            }
        }

        // Register bean as disposable.
        try {
            // 注册到 disposableBeans 里面,以便在销毁bean 的时候 可以运行指定的相关业务
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            //.......省略 抛出异常
        }
		// 返回Bean实例
        return exposedObject;
    }

}

// TODO

3.2.3 Bean 代理生成(AOP)

initializeBean() 重点方法,在属性注入完成后进行初始化Bean流程

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {
    
    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            // 执行后置处理器BeanPostProcessor的前置初始化方法 postProcessBeforeInitialization() 
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            // 调用 initialzingBean.afterPropertiesSet(),  init-mothod.init()方法  
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            //.......省略 抛出异常
        }
        if (mbd == null || !mbd.isSynthetic()) {
            // 执行后置处理器BeanPostProcessor的后置初始化方法 postProcessAfterInitialization() 
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }
}
e. BeanPostProcessor 扩展
public interface BeanPostProcessor {

	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

在 bean 初始化流程中,会先后调用 BeanPostProcessor的前置初始化、后置初始化方法。

  • 前置初始化:
  • 后置初始化:InfrastructureAdvisorAutoProxyCreator 实现了对@Transactional代理生成AOP代理对象,AsyncAnnotationBeanPostProcessor 实现了对@Async代理生成AOP代理对象

我们可以自定义类实现 BeanPostProcessor ,来达到扩展的效果。

// TODO

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值