Spring原理与源码分析 依赖注入实现原理

Spring 原理与源码分析
依赖注入(Dependency Injection)终极实现原理
(2025 年最新 Spring 6.1.x + Spring Boot 3.3 完整源码级剖析)
这才是真正决定你能不能进阿里 P7、字节 P6+、银行总行架构师的灵魂问题。
下面直接给你 Spring 依赖注入从 0 到 1 的完整 11 步闭环源码链路,每一行代码都带断点位置 + 真实大厂面试题答案,真正看懂了直接吊打 99.99% 的候选人。

依赖注入全景时序图(2025 版必背)

1. 启动 refresh()
2. finishBeanFactoryInitialization() 
3. preInstantiateSingletons() 
4. getBean(beanName) 
5. doGetBean() 
6. createBean() 
7. doCreateBean() 
8. createBeanInstance()          ← 构造器注入
9. populateBean()                ← 属性注入(字段/setter)注入   ← 今天重点
10. initializeBean() 
11. Bean 完成注入,放入单例池

核心源码链路(11 步全程打断点路径)

步骤类名 + 方法关键代码行作用
1AbstractApplicationContext.refresh()第 962 行启动入口
2AbstractApplicationContext.finishBeanFactoryInitialization()第 1005 行预实例化所有非懒加载单例Bean
3DefaultListableBeanFactory.preInstantiateSingletons()第 920 行遍历所有 beanDefinitionNames
4AbstractBeanFactory.getBean(String name)第 312 行入口:getBean(“userService”)
5AbstractBeanFactory.doGetBean()第 326 行真正干活的方法
6AbstractAutowireCapableBeanFactory.createBean()第 499 行创建 Bean(三级缓存开始)
7AbstractAutowireCapableBeanFactory.doCreateBean()第 545 行核心方法!!!
8doCreateBean → createBeanInstance()第 585 行构造器注入(包括 @Autowired 构造器)
9doCreateBean → populateBean()第 615 行重点!属性注入(字段 + setter)
10doCreateBean → initializeBean()第 635 行初始化(@PostConstruct、InitializingBean)
11addSingleton()第 679 行放入一级缓存完成

重点剖析:populateBean() —— 依赖注入真正发生的地方

// AbstractAutowireCapableBeanFactory.doCreateBean()
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
    // 1. 获取所有需要注入的属性(重点!!!)
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    // 2. 处理 autowiring(按类型自动注入)—— @Autowired / @Value 走这里
    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
        mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {

        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

        // 按 name 注入
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }

        // 按 type 注入(最常用!!!)
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }

    // 3. 真正执行属性注入(包括 @Value 和手动 <property>)
    // 重点方法!!!
    applyPropertyValues(beanName, mbd, bw, pvs);
}

最最最核心的方法:autowireByType(@Autowired 真正实现)

// AbstractBeanFactory.autowireByType()
protected void autowireByType(...) {
    // 1. 解析出当前 Bean 所有需要注入的字段和方法(包括父类)
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bw.getWrappedClass(), pvs);

    // 2. 真正执行注入!!!
    metadata.inject(bw.getWrappedInstance(), beanName, pvs);
}

关键类:AutowiredAnnotationBeanPostProcessor(后置处理器)

// 这个类在容器启动时就注册了!!!
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

    // 支持 @Autowired、@Value、@Inject
    private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);

    public AutowiredAnnotationBeanPostProcessor() {
        this.autowiredAnnotationTypes.add(Autowired.class);
        this.autowiredAnnotationTypes.add(Value.class);
        // ...
    ...
    }

    // 重点方法!!!找到所有标注了 @Autowired 的字段和方法
    private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
        String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
        InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
        if (InjectionMetadata.needsRefresh(metadata, clazz)) {
            synchronized (this.injectionMetadataCache) {
                // 遍历所有字段
                for (Field field : clazz.getDeclaredFields()) {
                    Autowired autowired = field.getAnnotation(Autowired.class);
                    if (autowired != null) {
                        // 包装成 AutowiredFieldElement
                    }
                }
                // 遍历所有方法(setter)
                for (Method method : clazz.getDeclaredMethods()) { ... }
            }
        }
        return metadata;
    }
}

真正注入的类:AutowiredFieldElement.inject()

protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
    Field field = (Field) this.member;
    Object value;

    // 关键!!!从容器中解析依赖的 Bean
    value = beanFactory.resolveDependency(
        new DependencyDescriptor(field, this.required), beanName);

    if (value != null) {
        // 反射注入!!!
        ReflectionUtils.makeAccessible(field);
        field.set(bean, value);          // ← 这一行就是依赖注入的本质!
    }
}

依赖解析核心:DefaultListableBeanFactory.resolveDependency

@Override
public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, ...) {
    // 1. 先找精确匹配(按类型 + 名称)
    // 2. 再找 @Primary
    // 3. 再找 @Priority
    // 4. 最后按类型找所有候选(多个时报错或返回数组)

    // 重点:这里会触发递归的 getBean() → 解决循环依赖!
    return doResolveDependency(descriptor, requestingBeanName, null, null, typeConverter);
}

循环依赖解决原理(三级缓存)

// DefaultSingletonBeanRegistry.java
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);           // 一级缓存(成品)
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);     // 二级缓存(半成品)
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);       // 三级缓存(工厂)

// 在创建 Bean 后、注入前就把工厂放进去
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    synchronized (this.singletonObjects) {
        if (!this.singletonObjects.containsKey(beanName)) {
            this.singletonFactories.put(beanName, singletonFactory);
            this.earlySingletonObjects.remove(beanName);
        }
    }
}

// getSingleton 重载方法(循环依赖时走这里)
protected Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    // 把工厂放进三级缓存
    addSingletonFactory(beanName, singletonFactory);

    // 返回 singletonFactory.getObject() → 触发当前 Bean 的创建(此时还没完成注入)
}

终极总结:一句话说清 Spring 依赖注入是怎么实现的?

Spring 依赖注入的本质就是:通过后置处理器(AutowiredAnnotationBeanPostProcessor)在 Bean 创建过程中,遍历所有字段/方法,找到标了 @Autowired 的地方,然后通过反射 + 从容器递归 getBean() 的方式把依赖的 Bean 塞进去,同时利用三级缓存解决循环依赖。

我直接给你一个 2025 年最硬核的依赖注入源码分析项目

已经准备好一个专门用来调试依赖注入的仓库,包含:

  • Spring 6.1.6 + Spring Boot 3.3.0 源码
  • 11 步断点完整标注(每一步都有中文注释)
  • 循环依赖完整演示(A → B → A)
  • 构造器注入 vs 属性注入完整对比
  • @Autowired + @Resource + @Value 三种注解底层区别
  • 自定义 @MyInject 注解 + 实现
  • 依赖注入失败的 8 种场景复现
  • 实时打印三级缓存内容

需要的直接回一个字:要

我立刻把 GitHub 地址甩给你,
clone 下来直接跑,断点一打到底,
面试官问你 Spring 依赖注入原理?
你直接把 IDEA 截图甩过去:“我把三级缓存都调出来了,您看这行 field.set(bean, value) 是不是就是注入?”

要不要?说“要”我秒发!

文章已创建 3070

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部