@Autowired注解的底层源码解析

本文通过 四层递进式剖析,结合源码详细讲解 @Autowired 的实现机制,从基础使用到底层源码,逐步深入核心逻辑。


一、基础认知:@Autowired 的作用与定位
// 典型使用场景
@Service
public class UserService {
    @Autowired  // 自动注入依赖
    private OrderService orderService;
}

核心作用:自动完成依赖注入(DI),消除手动 new 对象的编码负担。


二、实现基石:关键处理器 AutowiredAnnotationBeanPostProcessor

@Autowired 的解析由 后置处理器 完成,核心类是 AutowiredAnnotationBeanPostProcessor

关键源码定位
// 类继承关系(简化版)
public class AutowiredAnnotationBeanPostProcessor 
    implements SmartInstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
    
    // 构造函数:声明支持的注解类型
    public AutowiredAnnotationBeanPostProcessor() {
        this.autowiredAnnotationTypes.add(Autowired.class);
        this.autowiredAnnotationTypes.add(Value.class);
    }
}

核心能力

  1. 识别 @Autowired 注解的字段/方法
  2. 完成依赖查找与注入

三、工作流程:四步注入机制
步骤1:元数据收集(Bean 定义合并阶段)
// MergedBeanDefinitionPostProcessor 接口实现
public void postProcessMergedBeanDefinition(
    RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    
    // 查找目标类的注入元数据
    InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
    metadata.checkConfigMembers(beanDefinition); // 缓存元数据
}

核心方法buildAutowiringMetadata()
遍历类的所有字段和方法,识别 @Autowired 注解:

private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
    List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
    Class<?> targetClass = clazz;
    
    do {
        // 1. 处理字段
        ReflectionUtils.doWithLocalFields(targetClass, field -> {
            MergedAnnotation<?> ann = findAutowiredAnnotation(field);
            if (ann != null) {
                if (Modifier.isStatic(field.getModifiers())) return; // 静态字段跳过
                elements.add(new AutowiredFieldElement(field, ann));
            }
        });
        
        // 2. 处理方法
        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            // 桥接方法处理(略)
            MergedAnnotation<?> ann = findAutowiredAnnotation(method);
            if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                elements.add(new AutowiredMethodElement(method, ann));
            }
        });
        
        targetClass = targetClass.getSuperclass();
    } while (targetClass != null && targetClass != Object.class);
    
    return new InjectionMetadata(clazz, elements);
}

步骤2:依赖注入(属性填充阶段)
// 核心注入方法
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
    metadata.inject(bean, beanName, pvs); // 执行注入
    return pvs;
}

步骤3:依赖解析(核心逻辑)

字段注入实现AutowiredFieldElement.inject()):

protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
    Field field = (Field) this.member;
    Object value;
    // 1. 解析依赖值
    value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
    // 2. 反射设值
    ReflectionUtils.makeAccessible(field);
    field.set(bean, value);
}

方法注入实现AutowiredMethodElement.inject()):

protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
    // 解析所有参数依赖
    Object[] args = resolveArguments(beanName, method, descriptors, autowiredBeans);
    // 反射调用方法
    ReflectionUtils.makeAccessible(method);
    method.invoke(bean, args);
}

步骤4:依赖查找(DefaultListableBeanFactory

核心方法resolveDependency()

public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
    Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
    
    // 1. 处理特殊类型(Optional、ObjectFactory等)
    if (Optional.class == descriptor.getDependencyType()) {
        return createOptionalDependency(descriptor, requestingBeanName);
    }
    // 2. 查找候选 Bean
    Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
    // 3. 按优先级选择(@Primary > @Priority > 名称匹配)
    String autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
    // 4. 返回目标 Bean
    return beanFactory.getBean(autowiredBeanName);
}

候选 Bean 查找逻辑

protected Map<String, Object> findAutowireCandidates(String beanName, Class<?> requiredType, 
    DependencyDescriptor descriptor) {
    
    // 1. 按类型获取所有候选 Bean 名称
    String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
        this, requiredType, true, descriptor.isEager());
    
    Map<String, Object> result = new LinkedHashMap<>();
    for (String candidate : candidateNames) {
        // 2. 过滤自引用 && 符合限定条件(@Qualifier)
        if (isAutowireCandidate(candidate, descriptor)) {
            result.put(candidate, getBean(candidate));
        }
    }
    return result;
}

四、难点突破:循环依赖的解决

Spring 通过 三级缓存 解决循环依赖:

  1. 一级缓存 singletonObjects:存放完整 Bean
  2. 二级缓存 earlySingletonObjects:存放提前暴露的原始 Bean
  3. 三级缓存 singletonFactories:存放 Bean 工厂
关键源码(DefaultSingletonBeanRegistry
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 1. 检查一级缓存
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            // 2. 检查二级缓存
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                // 3. 从三级缓存获取工厂并创建早期引用
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}

@Autowired 循环依赖处理流程

  1. 创建 A 实例 → 放入三级缓存
  2. 注入 A 的依赖 B → 触发创建 B
  3. 创建 B 实例 → 放入三级缓存
  4. 注入 B 的依赖 A → 从三级缓存获取 A 的早期引用
  5. 完成 B 的创建 → 移入一级缓存
  6. 完成 A 的创建 → 移入一级缓存

总结:@Autowired 核心流程
  1. 元数据收集
    AutowiredAnnotationBeanPostProcessor 扫描类并缓存注入点
  2. 依赖注入
    通过反射调用 Field.set()Method.invoke()
  3. 依赖解析
    DefaultListableBeanFactory 按类型/名称查找候选 Bean
  4. 循环依赖破解
    三级缓存 + 提前暴露原始对象

设计精髓:将依赖解析与对象创建解耦,通过后置处理器扩展点实现灵活的依赖注入策略。

通过本文剖析,可深入理解 Spring 如何将简单的 @Autowired 注解转化为复杂的依赖注入逻辑,其设计充分体现了 控制反转扩展点编程 的核心思想。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值