文章目录
- findAutowireCandidates()实现
- 关于依赖注入中泛型注入的实现
- @Resource
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
该方法表示,传入一个依赖描述(DependencyDescriptor),该方法会根据该依赖描述从BeanFactory中找出对应的唯一的一个Bean对象。
下面来分析一下DefaultListableBeanFactory中**resolveDependency()**方法的具体实现,具体流程图:
https://www.processon.com/view/link/5f8d3c895653bb06ef076688
findAutowireCandidates()实现
根据类型找beanName的底层流程:https://www.processon.com/view/link/6135bb430e3e7412ecd5d1f2
对应执行流程图为:https://www.processon.com/view/link/5f8fdfa8e401fd06fd984f20
1.找出BeanFactory中类型为type的所有的Bean的名字,注意是名字,而不是Bean对象,因为我们可以根据BeanDefinition就能判断和当前type是不是匹配,不用生成Bean对象
2.把resolvableDependencies中key为type的对象找出来并添加到result中
3.遍历根据type找出的beanName,判断当前beanName对应的Bean是不是能够被自动注入
4.先判断beanName对应的BeanDefinition中的autowireCandidate属性,如果为false,表示不能用来进行自动注入,如果为true则继续进行判断
5.判断当前type是不是泛型,如果是泛型是会把容器中所有的beanName找出来的,如果是这种情况,那么在这一步中就要获取到泛型的真正类型,然后进行匹配,如果当前beanName和当前泛型对应的真实类型匹配,那么则继续判断
6.如果当前DependencyDescriptor上存在@Qualifier注解,那么则要判断当前beanName上是否定义了Qualifier,并且是否和当前DependencyDescriptor上的Qualifier相等,相等则匹配
7.经过上述验证之后,当前beanName才能成为一个可注入的,添加到result中
关于依赖注入中泛型注入的实现
首先在Java反射中,有一个Type接口,表示类型,具体分类为:
1.raw types:也就是普通Class
2.parameterized types:对应ParameterizedType接口,泛型类型
3.array types:对应GenericArrayType,泛型数组
4.type variables:对应TypeVariable接口,表示类型变量,也就是所定义的泛型,比如T、K
5.primitive types:基本类型,int、boolean
Spring中,但注入点是一个泛型时,也是会进行处理的。
- Spring扫描时发现UserService是一个Bean
- 那就取出注入点,也就是BaseService中的两个属性o、s
- 接下来需要按注入点类型进行注入,但是o和s都是泛型,所以Spring需要确定o和s的具体类型。
- 因为当前正在创建的是UserService的Bean,所以可以通过
userService.getClass().getGenericSuperclass().getTypeName() 获取到具体的泛型信息,比如
com.zhouyu.service.BaseService<com.zhouyu.service.OrderService,
com.zhouyu.service.StockService> - 然后再拿到UserService的父类BaseService的泛型变量: for (TypeVariable<? extends Class<?
typeParameter : userService.getClass().getSuperclass().getTypeParameters()) {
System.out.println(typeParameter.getName()); }
- 通过上面两段代码,就能知道,o对应的具体就是OrderService,s对应的具体类型就是
StockService - 然后再调用 oField.getGenericType() 就知道当前field使用的是哪个泛型,就能知道具体类型了
@Resource
@Resource注解底层工作流程图:
https://www.processon.com/view/link/5f91275f07912906db381f6e