Spring Boot 启动流程全解析:从 SpringApplication.run() 到 Bean 初始化与自动配置

这是springboot容器启动入口,

typescript 复制代码
@SpringBootApplication
public class SpringDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringDemoApplication.class, args);
    }

}

@SpringBootApplication 是一个复合注解,其核心注解有

less 复制代码
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

@EnableAutoConfiguration是自动配置的核心注解,启动了springboot的自动配置机制

其通过@Import({AutoConfigurationImportSelector.class})导入了自动配置最核心的类

这个类读取特定类路径下(META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports)下的自动配置类

依靠这些自动配置类,可以导入我们所需要的类 当我们引入了一些依赖,这些类的特定路径下的自动配置类被扫描

在refresh阶段,这些自动配置类会被初始化并且执行,其中的@Bean方法会被执行从而将bean导入到ioc容器

通过源码追踪发现

首先调用run启动应用

创建主类对象 用于后续解析注解等信息

创建springApplication对象 ,完成后续初始化工作

typescript 复制代码
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
    return run(new Class[]{primarySource}, args);
}

//run干了两件事 初始化springApplication 执行另一个run
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
    return (new SpringApplication(primarySources)).run(args);
}
kotlin 复制代码
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    this.addCommandLineProperties = true;
    this.addConversionService = true;
    this.headless = true;
    this.additionalProfiles = Collections.emptySet();
//上下文的创建工厂
    this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
    this.applicationStartup = ApplicationStartup.DEFAULT;
    this.properties = new ApplicationProperties();
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "'primarySources' must not be null");
    this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
    this.properties.setWebApplicationType(WebApplicationType.deduceFromClasspath());
    this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
//添加上下文初始化器  
//可以在应用上下文创建好后,refresh(bean创建)之前对容器上下文做一些操作 我们可以自定义实现ApplicationContextInitializer实现对应用的扩展(埋点1)
    this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
//添加监听器
    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = this.deduceMainApplicationClass();
}
kotlin 复制代码
public ConfigurableApplicationContext run(String... args) {
//创建并且启动计时器,计算启动耗时 后续可以通过
    Startup startup = SpringApplication.Startup.create();
    if (this.properties.isRegisterShutdownHook()) {
        shutdownHook.enableShutdownHookAddition();
    }

    DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
//spring上下文
    ConfigurableApplicationContext context = null;
    this.configureHeadlessProperty();
//获取并且启动所有的springApplicationRunListener(从spring.factories解析并且初始化所有springApplicationRunListener实例)
    SpringApplicationRunListeners listeners = this.getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);

    Throwable ex;
    try {

        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 环境准备,加载配置文件等,即做参数绑定,这里有监听器 通知监听器,从而使其调用environmentPrepared()
        ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
//打印banner
        Banner printedBanner = this.printBanner(environment);
//创建上下文对象实例!!!!!!!!!!!!!!!!!
        context = this.createApplicationContext();
        context.setApplicationStartup(this.applicationStartup);
//初始化配置 (埋点1提到的所有 ApplicationContextInitializer在这里被调用,进入源码查看)
        this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);

//最核心步骤 完成bean的创建和初始化!!!!!!!!!!
        this.refreshContext(context);

        this.afterRefresh(context, applicationArguments);

        startup.started();
        if (this.properties.isLogStartupInfo()) {
            (new StartupInfoLogger(this.mainApplicationClass, environment)).logStarted(this.getApplicationLog(), startup);
        }
//通知所有监听器 容器启动完成
        listeners.started(context, startup.timeTakenToStarted());
        this.callRunners(context, applicationArguments);
    } catch (Throwable var10) {
        ex = var10;
        throw this.handleRunFailure(context, ex, listeners);
    }

    try {
        if (context.isRunning()) {
//通知所有监听器 容器准备就绪
            listeners.ready(context, startup.ready());
        }
//返回容器启动的上下文,可以用来获取bean,管理生命周期等
        return context;
    } catch (Throwable var9) {
        ex = var9;
        throw this.handleRunFailure(context, ex, (SpringApplicationRunListeners)null);
    }
}

解读容器初始化

kotlin 复制代码
private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
//保存环境配置到上下文 用于后续构建bean时将参数配置等注入等,后续的@ConfigurationProperties都依赖于这个参数
    context.setEnvironment(environment);
    this.postProcessApplicationContext(context);
    this.addAotGeneratedInitializerIfNecessary(this.initializers);
//应用所有的ApplicationContextInitializer 调用其方法  埋点3!!!!!!!!
    this.applyInitializers(context);
//告诉监听器,上下文准备好了 调用pre
    listeners.contextPrepared(context);
    bootstrapContext.close(context);
    if (this.properties.isLogStartupInfo()) {
        this.logStartupInfo(context.getParent() == null);
        this.logStartupInfo(context);
        this.logStartupProfileInfo(context);
    }
//获取beanFactory 即ioc容器底层
    ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//添加两个bean
    beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
    if (printedBanner != null) {
        beanFactory.registerSingleton("springBootBanner", printedBanner);
    }

    if (beanFactory instanceof AbstractAutowireCapableBeanFactory autowireCapableBeanFactory) {
        autowireCapableBeanFactory.setAllowCircularReferences(this.properties.isAllowCircularReferences());
        if (beanFactory instanceof DefaultListableBeanFactory listableBeanFactory) {
            listableBeanFactory.setAllowBeanDefinitionOverriding(this.properties.isAllowBeanDefinitionOverriding());
        }
    }

    if (this.properties.isLazyInitialization()) {
        context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
    }

    if (this.properties.isKeepAlive()) {
        context.addApplicationListener(new KeepAlive());
    }

    context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));
    if (!AotDetector.useGeneratedArtifacts()) {
        Set<Object> sources = this.getAllSources();
        Assert.state(!ObjectUtils.isEmpty(sources), "No sources defined");
        this.load(context, sources.toArray(new Object[0]));
    }
//context加载完毕
    listeners.contextLoaded(context);
}

可以看到通过迭代器,遍历每个 ApplicationContextInitializer,调用其initialize方法,将上下文传进去

ini 复制代码
protected void applyInitializers(ConfigurableApplicationContext context) {
    Iterator var2 = this.getInitializers().iterator();

    while(var2.hasNext()) {
        ApplicationContextInitializer initializer = (ApplicationContextInitializer)var2.next();
        Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), ApplicationContextInitializer.class);
        Assert.state(requiredType.isInstance(context), "Unable to call initializer");
        initializer.initialize(context);
    }

}

同时还有 调用每个 SpringApplicationRunListener 调用其contextPrepared

ini 复制代码
 listeners.contextPrepared(context);

做个demo测试一下

java 复制代码
/**
 * @author omenkk7
 * @description
 * @create 2025/10/10
 */
public class myApplicationContextInitializer implements ApplicationContextInitializer {


    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
        System.out.println("=======================================");
        System.out.println("我是一个ApplicationContextInitializer ");
        System.out.println("获取了beanFactory");
        System.out.println("获取了bean集合迭代器");
        Iterator<String> beanNamesIterator = beanFactory.getBeanNamesIterator();
        int i=1;
        while(beanNamesIterator.hasNext()){
            String beanName = beanNamesIterator.next();
            System.out.println("beanName:"+beanName);
            i++;
        }
        System.out.println("一共有"+i+"个bean,此行为发生在refreshContext(context)之前");
        System.out.println("=======================================");


    }
}
//=====================
public class MyCustomRunListener implements SpringApplicationRunListener {

    public MyCustomRunListener(SpringApplication application, String[] args) {

    }



    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("//////////////////////////////////////");
        System.out.println("我是一个SpringApplicationRunListener ");
        System.out.println("上下文已创建,但还没加载 Bean!");
        System.out.println("获取了beanFactory");
        System.out.println("获取了bean集合迭代器");
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        Iterator<String> beanNamesIterator = beanFactory.getBeanNamesIterator();
        int i=1;
        while(beanNamesIterator.hasNext()){
            String beanName = beanNamesIterator.next();
            System.out.println("beanName:"+beanName);
            i++;
        }
        System.out.println("一共有"+i+"个bean,此行为发生在refreshContext(context)之前");
        System.out.println("//////////////////////////////////////");

    }

//======================


//写一个bean
@Component()
public class testBean {

private int i;



}


按照规定写到src/main/resources/META-INF/spring.factories下

org.springframework.context.ApplicationContextInitializer=\
  cn.omenkk.springdemo.ApplicationContextInitializerMap.myApplicationContextInitializer




# 注册自定义的 SpringApplicationRunListener
org.springframework.boot.SpringApplicationRunListener=\
  cn.omenkk.springdemo.listener.MyCustomRunListener

输出

vbnet 复制代码
  .   ____          _            __ _ _
 /\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )___ | '_ | '_| | '_ / _` | \ \ \ \
 \/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |___, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.5.6)

=======================================
我是一个ApplicationContextInitializer 
获取了beanFactory
获取了bean集合迭代器
beanName:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
beanName:org.springframework.context.annotation.internalAutowiredAnnotationProcessor
beanName:org.springframework.context.annotation.internalCommonAnnotationProcessor
beanName:org.springframework.context.event.internalEventListenerProcessor
beanName:org.springframework.context.event.internalEventListenerFactory
beanName:org.springframework.boot.context.ContextIdApplicationContextInitializer$ContextId
一共有7个bean,此行为发生在refreshContext(context)之前
=======================================
//////////////////////////////////////
我是一个SpringApplicationRunListener 
上下文已创建,但还没加载 Bean!
获取了beanFactory
获取了bean集合迭代器
beanName:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
beanName:org.springframework.context.annotation.internalAutowiredAnnotationProcessor
beanName:org.springframework.context.annotation.internalCommonAnnotationProcessor
beanName:org.springframework.context.event.internalEventListenerProcessor
beanName:org.springframework.context.event.internalEventListenerFactory
beanName:org.springframework.boot.context.ContextIdApplicationContextInitializer$ContextId
beanName:autoConfigurationReport
一共有8个bean,此行为发生在refreshContext(context)之前
//////////////////////////////////////
2025-10-10T15:32:14.830+08:00  INFO 32456 --- [spring-demo] [           main] c.o.springdemo.SpringDemoApplication     : Starting SpringDemoApplication using Java 17.0.12 with PID 32456 (G:\code-project\springDemo\spring-demo\target\classes started by 连庆辉 in G:\code-project\springDemo\spring-demo)
2025-10-10T15:32:14.832+08:00  INFO 32456 --- [spring-demo] [           main] c.o.springdemo.SpringDemoApplication     : No active profile set, falling back to 1 default profile: "default"
2025-10-10T15:32:15.160+08:00  INFO 32456 --- [spring-demo] [           main] c.o.springdemo.SpringDemoApplication     : Started SpringDemoApplication in 0.647 seconds (process running for 1.011)

上述的bean是springboot应用自携带的基础设施,负责读取@Configuration,@Autowired,@EventListener等注解的核心功能,读者可自行查阅

prepareContext方法后续源码本文不再解释 接下来看 refreshContext

在上述方法中,我们知道beanFactory已经构建

spring.factories的内容被读取

这些基础内容已经被初始化构建,接下来自然能构建其余bean了

typescript 复制代码
private void refreshContext(ConfigurableApplicationContext context) {
    if (this.properties.isRegisterShutdownHook()) {
        shutdownHook.registerApplicationContext(context);
    }

    this.refresh(context);
}
typescript 复制代码
protected void refresh(ConfigurableApplicationContext applicationContext) {
    applicationContext.refresh();
}
kotlin 复制代码
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext

public void refresh() throws BeansException, IllegalStateException {
    this.startupShutdownLock.lock();

    try {
        this.startupShutdownThread = Thread.currentThread();
        StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
        this.prepareRefresh();
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//做默认配置,比如classLoader设置,
        this.prepareBeanFactory(beanFactory);

        try {
            this.postProcessBeanFactory(beanFactory);
            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 在这个方法内部调用了BeanDefinitionRegistryPostProcessor等处理器,将自动配置类进行注册实例化,是自动配置的关键
//那么他是怎么知道要注册哪些自动配置类的呢,就是通过AutoConfigurationImportSelector.class这个了,spring先前创建了这个类的实例,调用其方法,
//将spring.factories声明的自动配置类路径进行收集   
            this.invokeBeanFactoryPostProcessors(beanFactory);
            this.registerBeanPostProcessors(beanFactory);
            beanPostProcess.end();
            this.initMessageSource();
            this.initApplicationEventMulticaster();
//创建web容器 即tomcat的启动
            this.onRefresh();
//注册监听器ApplicationListener
            this.registerListeners();
//初始化所有单例bean 
            this.finishBeanFactoryInitialization(beanFactory);
            this.finishRefresh();
        } catch (Error | RuntimeException var12) {
            Throwable ex = var12;
            if (this.logger.isWarnEnabled()) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + String.valueOf(ex));
            }

            this.destroyBeans();
            this.cancelRefresh(ex);
            throw ex;
        } finally {
            contextRefresh.end();
        }
    } finally {
        this.startupShutdownThread = null;
        this.startupShutdownLock.unlock();
    }

}

我们可以看到,在上述代码,自动配置类,web容器,Applicationlisteners,普通bean先后被初始化

结合上述内容,spring是怎么实现自动配置的呢

很显然,我们引入了所需依赖的Jar包。那么应用启动时,@EnableAutoConfiguration的@import(AutoConfigurationImportSelector.class)的AutoConfigurationImportSelector.class会被初始化,该实例对象会去读取程序下所有jar包的指定路径下的类名称在refresh()阶段,之后,从而加载这些自动配置类,并且加载其@bean方法标识的bean(你在springboot应用中应该见过) 实现bean的自动化配置

而对于应用本身的自动配置类,则只需要通过@Configuration实现配置即可

@ComponentScan注解即可将这些对象也识别出来,和@EnableAutoConfiguration识别出的外部依赖的自动配置类一起在this.invokeBeanFactoryPostProcessors(beanFactory);在这个阶段 将其BeanDefinition(bean配置定义)注册到容器中(尚未发生实例)

kotlin 复制代码
 this.finishBeanFactoryInitialization(beanFactory);

在方法内部调用了

ini 复制代码
beanFactory.preInstantiateSingletons();

继续点进去看

ini 复制代码
//调用该方法
public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Pre-instantiating singletons in " + String.valueOf(this));
        }

        List<String> beanNames = new ArrayList(this.beanDefinitionNames);
        this.preInstantiationThread.set(DefaultListableBeanFactory.PreInstantiation.MAIN);
        this.mainThreadPrefix = getThreadNamePrefix();

        try {
            List<CompletableFuture<?>> futures = new ArrayList();
            Iterator var3 = beanNames.iterator();

            while(var3.hasNext()) {
                String beanName = (String)var3.next();
                RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
如果bean不是抽象的 并且是单例bean
                if (!mbd.isAbstract() && mbd.isSingleton()) {
//调用该方法创建bean
                    CompletableFuture<?> future = this.preInstantiateSingleton(beanName, mbd);
                    if (future != null) {
                        futures.add(future);
                    }
                }
            }

            if (!futures.isEmpty()) {
                try {
                    CompletableFuture.allOf((CompletableFuture[])futures.toArray(new CompletableFuture[0])).join();
                } catch (CompletionException var10) {
                    CompletionException ex = var10;
                    ReflectionUtils.rethrowRuntimeException(ex.getCause());
                }
            }
        } finally {
            this.mainThreadPrefix = null;
            this.preInstantiationThread.remove();
        }

        Iterator var12 = beanNames.iterator();

        while(var12.hasNext()) {
            String beanName = (String)var12.next();
            Object singletonInstance = this.getSingleton(beanName, false);
            if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {
                StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);
                smartSingleton.afterSingletonsInstantiated();
                smartInitialize.end();
            }
        }

    }

    @Nullable
    private CompletableFuture<?> preInstantiateSingleton(String beanName, RootBeanDefinition mbd) {
        if (mbd.isBackgroundInit()) {
            Executor executor = this.getBootstrapExecutor();
            if (executor != null) {
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    String[] var5 = dependsOn;
                    int var6 = dependsOn.length;

                    for(int var7 = 0; var7 < var6; ++var7) {
                        String dep = var5[var7];
//获取bean------
                        this.getBean(dep);
                    }
                }

                CompletableFuture<?> future = CompletableFuture.runAsync(() -> {
                    this.instantiateSingletonInBackgroundThread(beanName);
                }, executor);
                this.addSingletonFactory(beanName, () -> {
                    try {
                        future.join();
                    } catch (CompletionException var2) {
                        CompletionException ex = var2;
                        ReflectionUtils.rethrowRuntimeException(ex.getCause());
                    }

                    return future;
                });
                return !mbd.isLazyInit() ? future : null;
            }

            if (this.logger.isInfoEnabled()) {
                this.logger.info("Bean '" + beanName + "' marked for background initialization without bootstrap executor configured - falling back to mainline initialization");
            }
        }

        if (!mbd.isLazyInit()) {
            try {
                this.instantiateSingleton(beanName);
            } catch (BeanCurrentlyInCreationException var9) {
                this.logger.info("Bean '" + beanName + "' marked for pre-instantiation (not lazy-init) but currently initialized by other thread - skipping it in mainline thread");
            }
        }

        return null;
    }

typescript 复制代码
public Object getBean(String name) throws BeansException {
    return this.doGetBean(name, (Class)null, (Object[])null, false);
}

kotlin 复制代码
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
    String beanName = this.transformedBeanName(name);
//从三级缓存获取,如果为空说明未初始化!!!!!这里非常重要,后续讲解
    Object sharedInstance = this.getSingleton(beanName);
    Object beanInstance;
    if (sharedInstance != null && args == null) {
        if (this.logger.isTraceEnabled()) {
            if (this.isSingletonCurrentlyInCreation(beanName)) {
                this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
            } else {
                this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }

        beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
    } else {
        if (this.isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        BeanFactory parentBeanFactory = this.getParentBeanFactory();
        if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
            String nameToLookup = this.originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                AbstractBeanFactory abf = (AbstractBeanFactory)parentBeanFactory;
                return abf.doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
            }

            if (args != null) {
                return parentBeanFactory.getBean(nameToLookup, args);
            }

            if (requiredType != null) {
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }

            return parentBeanFactory.getBean(nameToLookup);
        }

        if (!typeCheckOnly) {
            this.markBeanAsCreated(beanName);
        }

        StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);

        try {
            if (requiredType != null) {
                Objects.requireNonNull(requiredType);
                beanCreation.tag("beanType", requiredType::toString);
            }

            RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
            this.checkMergedBeanDefinition(mbd, beanName, args);
            String[] dependsOn = mbd.getDependsOn();
            String[] prototypeInstance;
            if (dependsOn != null) {
                prototypeInstance = dependsOn;
                int var13 = dependsOn.length;

                for(int var14 = 0; var14 < var13; ++var14) {
                    String dep = prototypeInstance[var14];
                    if (this.isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }

                    this.registerDependentBean(dep, beanName);

                    try {
                        this.getBean(dep);
                    } catch (NoSuchBeanDefinitionException var33) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var33);
                    } catch (BeanCreationException var34) {
                        BeanCreationException ex = var34;
                        if (requiredType != null) {
                            String var10002 = mbd.getResourceDescription();
                            String var10004 = ex.getBeanName();
                            throw new BeanCreationException(var10002, beanName, "Failed to initialize dependency '" + var10004 + "' of " + requiredType.getSimpleName() + " bean '" + beanName + "': " + ex.getMessage(), ex);
                        }

                        throw ex;
                    }
                }
            }

            if (mbd.isSingleton()) {
//如果一级缓存二级缓存都没有并且是单例就会进入这个分支 对于三级缓存是什么可以看一下后续的代码块解释
                sharedInstance = this.getSingleton(beanName, () -> {
                    try {
//创造bean !!!!!继续跳
                        return this.createBean(beanName, mbd, args);
                    } catch (BeansException var5) {
                        BeansException ex = var5;
                        this.destroySingleton(beanName);
                        throw ex;
                    }
                });
                beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            } else if (mbd.isPrototype()) {
                prototypeInstance = null;

                Object prototypeInstance;
                try {
                    this.beforePrototypeCreation(beanName);
                    prototypeInstance = this.createBean(beanName, mbd, args);
                } finally {
                    this.afterPrototypeCreation(beanName);
                }

                beanInstance = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            } else {
                String scopeName = mbd.getScope();
                if (!StringUtils.hasLength(scopeName)) {
                    throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
                }

                Scope 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, () -> {
                        this.beforePrototypeCreation(beanName);

                        Object var4;
                        try {
                            var4 = this.createBean(beanName, mbd, args);
                        } finally {
                            this.afterPrototypeCreation(beanName);
                        }

                        return var4;
                    });
                    beanInstance = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                } catch (IllegalStateException var32) {
                    throw new ScopeNotActiveException(beanName, scopeName, var32);
                }
            }
        } catch (BeansException var35) {
            BeansException ex = var35;
            beanCreation.tag("exception", ex.getClass().toString());
            beanCreation.tag("message", String.valueOf(ex.getMessage()));
            this.cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        } finally {
            beanCreation.end();
            if (!this.isCacheBeanMetadata()) {
                this.clearMergedBeanDefinition(beanName);
            }

        }
    }

    return this.adaptBeanInstance(name, beanInstance, requiredType);
}
ini 复制代码
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
    }

    if (instanceWrapper == null) {
        instanceWrapper = this.createBeanInstance(beanName, mbd, args);
    }

    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    synchronized(mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable var17) {
                Throwable ex = var17;
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex);
            }

            mbd.markAsPostProcessed();
        }
    }

    boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
    if (earlySingletonExposure) {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
        }

        this.addSingletonFactory(beanName, () -> {
            return this.getEarlyBeanReference(beanName, mbd, bean);
        });
    }

    Object exposedObject = bean;

    try {
        this.populateBean(beanName, mbd, instanceWrapper);
//初始化bean方法!!!!!!!!!!!!!!!!!!!!!---------3
        exposedObject = this.initializeBean(beanName, exposedObject, mbd);
    } catch (Throwable var18) {
        Throwable ex = var18;
        if (ex instanceof BeanCreationException bce) {
            if (beanName.equals(bce.getBeanName())) {
                throw bce;
            }
        }

        throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex);
    }

    if (earlySingletonExposure) {
        Object earlySingletonReference = this.getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                String[] dependentBeans = this.getDependentBeans(beanName);
                Set<String> actualDependentBeans = CollectionUtils.newLinkedHashSet(dependentBeans.length);
                String[] var12 = dependentBeans;
                int var13 = dependentBeans.length;

                for(int var14 = 0; var14 < var13; ++var14) {
                    String dependentBean = var12[var14];
                    if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }

                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    try {
        this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
        return exposedObject;
    } catch (BeanDefinitionValidationException var16) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
    }
}
=============================================================

    protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

        if (instanceWrapper == null) {
            instanceWrapper = 
//1---实例化
this.createBeanInstance(beanName, mbd, args);
        }

        Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        synchronized(mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                } catch (Throwable var17) {
                    Throwable ex = var17;
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex);
                }

                mbd.markAsPostProcessed();
            }
        }

        boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
        if (earlySingletonExposure) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
            }

            this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
        }

        Object exposedObject = bean;

        try {
//2---设置属性值
            this.populateBean(beanName, mbd, instanceWrapper);
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            Throwable ex = var18;
            if (ex instanceof BeanCreationException bce) {
                if (beanName.equals(bce.getBeanName())) {
                    throw bce;
                }
            }

            throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex);
        }

        if (earlySingletonExposure) {
            Object earlySingletonReference = this.getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                    String[] dependentBeans = this.getDependentBeans(beanName);
                    Set<String> actualDependentBeans = CollectionUtils.newLinkedHashSet(dependentBeans.length);
                    String[] var12 = dependentBeans;
                    int var13 = dependentBeans.length;

                    for(int var14 = 0; var14 < var13; ++var14) {
                        String dependentBean = var12[var14];
                        if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }

                    if (!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

        try {
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
            return exposedObject;
        } catch (BeanDefinitionValidationException var16) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
        }
    }

=========================================================





//调用构造函数创建bean
   protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//获取bean的类对象
        Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
        } else {
            if (args == null) {
                Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
                if (instanceSupplier != null) {
                    return this.obtainFromSupplier(instanceSupplier, beanName, mbd);
                }
            }

            if (mbd.getFactoryMethodName() != null) {
                return this.instantiateUsingFactoryMethod(beanName, mbd, args);
            } else {
                boolean resolved = false;
                boolean autowireNecessary = false;
                if (args == null) {
                    synchronized(mbd.constructorArgumentLock) {
                        if (mbd.resolvedConstructorOrFactoryMethod != null) {
                            resolved = true;
                            autowireNecessary = mbd.constructorArgumentsResolved;
                        }
                    }
                }
//接下来就是调用构造函数创建bean了
                if (resolved) {
                    return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
                } else {
                    Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
                    if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
                        ctors = mbd.getPreferredConstructors();
                        return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
                    } else {
                        return this.autowireConstructor(beanName, mbd, ctors, args);
                    }
                }
            }
        }
    }



//========设置属性值
将Autowire等属性的自动装配进行装配

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        if (bw == null) {
            if (mbd.hasPropertyValues()) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
        } else if (bw.getWrappedClass().isRecord()) {
            if (mbd.hasPropertyValues()) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to a record");
            }
        } else {
            if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                Iterator var4 = this.getBeanPostProcessorCache().instantiationAware.iterator();

                while(var4.hasNext()) {
                    InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var4.next();
                    if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        return;
                    }
                }
            }

            PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
            int resolvedAutowireMode = mbd.getResolvedAutowireMode();
            if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
                MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
                if (resolvedAutowireMode == 1) {
                    this.autowireByName(beanName, mbd, bw, newPvs);
                }

                if (resolvedAutowireMode == 2) {
                    this.autowireByType(beanName, mbd, bw, newPvs);
                }

                pvs = newPvs;
            }

            if (this.hasInstantiationAwareBeanPostProcessors()) {
                if (pvs == null) {
                    pvs = mbd.getPropertyValues();
                }

                PropertyValues pvsToUse;
                for(Iterator var11 = this.getBeanPostProcessorCache().instantiationAware.iterator(); var11.hasNext(); pvs = pvsToUse) {
                    InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var11.next();
                    pvsToUse = bp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        return;
                    }
                }
            }

            boolean needsDepCheck = mbd.getDependencyCheck() != 0;
            if (needsDepCheck) {
                PropertyDescriptor[] filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
            }

            if (pvs != null) {
                this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
            }

        }
    }

//================
    protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
//检查是否实现了aware接口
//当你Component("abc")实际就是实现了beanNameAware接口 可以修改bean的名字
        this.invokeAwareMethods(beanName, bean);
//调用BeanPostProcessor前置方法
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = 
/this.applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            Throwable ex = var6;
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, ex.getMessage(), ex);
        }

//调用BeanPostProcessor后置方法
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

在这里提及了BeanPostProcessor,通过这个接口 我们可以在bean初始化前后添加处理逻辑,对bean进行操作

这里不得不提到spring一个非常重要的东西,aop

当你当spring使用了使用了aop,其实就是在生成了一个BeanPostProcessor 其后置处理方法会判断该bean是否需要被代理

如果需要的话,就创建代理对象放到容器中

什么是aop呢?

aop就是面向切面编程 寻找流程的切入点 进行编程 就是把公共逻辑抽出来,使得开发者可以更加专注业务逻辑开发

spring的aop有两种实现,基于动态代理 和@Aspectj注解(吟唱八股hhh)

另外提一下Aspectj这个框架功能很强大,可以在编译期,类加载期就进行织入

什么是spring的三级缓存 在本段代码下面

DefaultSingletonEBeanRegistrys管理着三级缓存

通过这三个集合结合spring内部代码实现管理单例bean的缓存及获取 从而实现bean的单例特性 可以用来解决循环依赖

代码可能出现循环依赖,如果一个一个直接构造完毕可能会有空指针

通过三级缓存来保存未初始化完成的bean,同时创建一个bean之前判断其是否存在于三级缓存,从而保证bean正常创建

scala 复制代码
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    private static final int SUPPRESSED_EXCEPTIONS_LIMIT = 100;
    final Lock singletonLock = new ReentrantLock();//这个锁很重要,保证并发情况下bean指只被创建一次 保证单例性
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);//一级缓存 保存完成的bean对象
    private final Map<String, ObjectFactory<?>> singletonFactories = new ConcurrentHashMap(16);//三级缓存,保存bean名-bean的创建工厂
    private final Map<String, Consumer<Object>> singletonCallbacks = new ConcurrentHashMap(16);//
    private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);//二级缓存 存储未完全实例化的bean对象
kotlin 复制代码
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从一级缓存存在bean实例对象  如果不为空 说明创建完毕了 直接返回
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
//从二级缓存获取
        singletonObject = this.earlySingletonObjects.get(beanName);
        if (singletonObject == null && allowEarlyReference) {
            if (!this.singletonLock.tryLock()) {
                return null;
            }

            try {
//从三级缓存获取
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    singletonObject = this.earlySingletonObjects.get(beanName);
                    if (singletonObject == null) {
                        ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                        if (singletonFactory != null) {
                            singletonObject = singletonFactory.getObject();
                            if (this.singletonFactories.remove(beanName) != null) {
                                this.earlySingletonObjects.put(beanName, singletonObject);
                            } else {
                                singletonObject = this.singletonObjects.get(beanName);
                            }
                        }
                    }
                }
            } finally {
                this.singletonLock.unlock();
            }
        }
    }

    return singletonObject;
}

在这个过程中,会将所有生效的bean进行实例化

同时你应该知道这个注解 @Configuration 以及听说过按需生效

这个注解的作用就是条件化注册,只有某个类存在他会进行自动配置

那么当我引入一个jar包,我要他的bean按需生效,就可以采用这个注解

通过自动配置机制,实现了引入依赖即可生效

依赖提供方通过条件注解

我们在应用中通过@Configuration 结合其条件化注册,从而实现定制效果

或者防止由于某些类不存在导致初始化丢失

相关推荐
间彧1 小时前
Kubernetes的Pod与Docker Compose中的服务在概念上有何异同?
后端
间彧1 小时前
从开发到生产,如何将Docker Compose项目平滑迁移到Kubernetes?
后端
间彧1 小时前
如何结合CI/CD流水线自动选择正确的Docker Compose配置?
后端
间彧1 小时前
在多环境(开发、测试、生产)下,如何管理不同的Docker Compose配置?
后端
间彧1 小时前
如何为Docker Compose中的服务配置健康检查,确保服务真正可用?
后端
间彧1 小时前
Docker Compose和Kubernetes在编排服务时有哪些核心区别?
后端
间彧1 小时前
如何在实际项目中集成Arthas Tunnel Server实现Kubernetes集群的远程诊断?
后端
brzhang2 小时前
读懂 MiniMax Agent 的设计逻辑,然后我复刻了一个MiniMax Agent
前端·后端·架构
草明2 小时前
Go 的 IO 多路复用
开发语言·后端·golang
蓝-萧2 小时前
Plugin ‘mysql_native_password‘ is not loaded`
java·后端