Spring-依赖注入的处理过程

前置知识

1 入口 DefaultListableBeanFactory#resolveDependency

2 每个依赖都有对应的DependencyDescriptor

3 自定绑定候选对象处理器AutowireCapableBeanFactory

注入处理

我们可以看到AutowireCapableBeanFactory中有两个方法:

第一个是单个注入:

java 复制代码
@Nullable
	Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;

还有一个是Set集合注入:

java 复制代码
@Nullable
	Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
java 复制代码
public class AnnotationDependencyInjectResolutionDemo {
    @Autowired
    private Person person;
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(AnnotationDependencyInjectResolutionDemo.class);
        context.refresh();
        QualifierAnnotationDependencyInjectDemo bean = context.getBean(QualifierAnnotationDependencyInjectDemo.class);
    }
 }

我们直接断点看一下DependencyDescriptor 里面的信息:

DependencyDescriptor 描述了我们要注入的目标的一些信息,申明类,字段名称,是否必须对应的就是Autowired的知否必须,eager是否是肌饿模式(实时注入),一般不用懒加载都是肌饿的。

注入过程

1 普通的字段注入

java 复制代码
@Autowired
private Person person;
  • 字段注入前面的判断都会跳过进入到下面这个方法

  • 让后进入的下一个核心方法

进入这个方法:

候选的Bean是通过上面这个方法找到的,并且返回的时候将Bean对象放入到Map中。

然后我们如果我们多个bean,determineAutowireCandidate这个方法会决定一个Bean,决定的方式为如果使用了Primary就注入PrimaryBean否则Ordered根据这个接口定义的优先级来寻找,数字越低优先级越高:

2 集合注入

java 复制代码
@Autowired
private Collection<Person> personGroupAll;

集合注入核心逻辑会走到下面这个方法,这个方法返回的时候multipleBeans已经不为空了这个这个直接返回。

为什么上面可以直接返回呢,因为在resolveMultipleBeans方法中,判断了注入的类型如果是集合类型,也是走的一样的逻辑findAutowireCandidates找到候选的Bean进行返回。

3 懒加载

java 复制代码
@Autowired
@Lazy
private Person person;

在懒注入的时候我们在这个方法已经有值了,所以逻辑在这一步就结束了,返回的是一个代理对象。

这个对象是cglib提升后的对象:

4 Optional注入

java 复制代码
@Autowired
  private Optional<Person> person;

核心逻辑是走下面

其实里面的逻辑是一样的,只是最后封装为Optional:

@Autowired的原理

会先调用AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition

然后调用这个方法:

最后通过反射进行注入:

相关推荐
喵了几个咪5 分钟前
GoWind CMS 拆解:在 Go 里给 TipTap 搭一套 Yjs 协同后端
开发语言·后端·golang
Flynt12 分钟前
我把微信运动的排行榜和定点推送复刻了一遍:100万次步数更新只要4秒,坑在别处
redis·后端·性能优化
文丑颜不良啊1 小时前
LeetCode876~900题目解析
java·leetcode
aloha_7892 小时前
Java 基础、集合、异常与 JUnit 5 速查
java·junit·sqlserver
CarIise2 小时前
SpringMVC 异常处理与拦截器
大数据·spring
知守观2 小时前
设计模式实战:从真实老项目中看标准模板方法与工厂的落地
java·spring·设计模式
独隅2 小时前
Claude API 实战教程:从入门到完整项目
android·java·数据库·claude·claude code
_孤傲_2 小时前
快速掌握 MySQL 语法
数据库·后端·mysql
Wang's Blog3 小时前
Java 项目实战: 交友项目 - 圈子功能实现:总结
java·开发语言·交友
SL_staff3 小时前
JVS私有化文档系统上线避坑指南:5大运维与业务协同断点及检测加固实践
java·开源·全栈