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 结合其条件化注册,从而实现定制效果

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

相关推荐
Java中文社群7 小时前
我的网站被攻击了!
后端
程序定小飞7 小时前
基于springboot的在线商城系统设计与开发
java·数据库·vue.js·spring boot·后端
shengjk17 小时前
一文搞懂 java 中 POJO 和 bean 区别
后端
野犬寒鸦7 小时前
从零起步学习Redis || 第十一章:主从切换时的哨兵机制如何实现及项目实战
java·服务器·数据库·redis·后端·缓存
间彧7 小时前
AspectJ详解与项目实战指南
后端
爱读源码的大都督7 小时前
RAG效果不理想?试试用魔法打败魔法:让大模型深度参与优化的三阶段实战
java·人工智能·后端
间彧8 小时前
Spring Boot @Lazy注解详解与实战应用
后端
间彧8 小时前
SpEL表达式详解与应用实战
后端
源码部署28 小时前
【大厂学院】微服务框架核心源码深度解析
后端