DefaultListableBeanFactory.resolveDependency
该方法接收依赖描述器DependencyDescriptor,里面封装了注入点的成员(字段或方法参数),以及所在的beanClass<br>
如果注入点类型是Optional,required设为false,doResolveDependency获取真正的依赖对象封装进Optional,
如果注入点类型是ObjectFactory或ObjectProvider,直接封装成它们的实现类DependencyObjectProvider返回,在getObject的时候才会真正doResolveDependency获取依赖对象,类似于懒加载的方式,ObjectFactory或ObjectProvider还可以在嵌套一个Optional<br>
如果注入点(字段、方法、方法参数、构造器)带了@Lazy注解,生成一个代理对象赋值给注入点,代理对象在使用时才会进行doResolveDependency依赖注入<br>
@Lazy还可以用在类型上,表示当前bean是懒加载的,容器启动时不会创建
DefaultListableBeanFactory.doResolveDependency<br>
该方法功能:根据注入点的依赖描述符和beanName获取真正的依赖对象,beanName是用来判断自引用的
先判断是否有@Value,如果有,获取到@Value的值,可能从environment获取,获取到后直接返回<br>
如果注入点类型是数组、集合、map,根据元素类型从beanFactory中获取bean实例直接返回<br>
java.lang.reflect.Type的子类型有Class、ParameterizedType(参数化类型)、GenericArrayType(泛型数组)、WildcardType(通配符类型)、TypeVariable(泛型变量),后4个就是泛型<br>
ParameterizedType(参数化类型):List<String>,List<T>,getActualTypeArguments可以获取到类型参数,String或T<br>
<font color="#ff0000">参数化类型在继承、实现、字段、方法参数、返回值中指定了具体类型时,运行期是可以通过反射获取到的</font>
DefaultListableBeanFactory.findAutowireCandidates
该方法功能:根据<b>类型</b>从beanDefinitionMap中找到候选的beanName,以及beanClass,也有可能是实例化后的单例bean<font color="#ff0000"></font>
<font color="#ff0000">如果单例池中没有,此时只会进行类型加载,不实例化</font>,因为还需要进一步过滤,避免不需要的bean被实例化了
会从当前beanFactory和父beanFactory找,都加进结果里<br>
对于每个注点,都会遍历所有的beanName查看类型是否匹配,如果遍历到的是FactoryBean,FactoryBean本身的类型和FactoryBean.getObjectType的类型都会参与匹配
<font color="#ff0000">依赖注入可以注入FactoryBean.getObject返回的对象,注入点的类型与FactoryBean.getObjectType相同即可</font>
<b>处理自引用</b>:注入点beanName和当前类相同时,会先排除当前bean,如果除当前bean没有候选者,再考虑自引用<br>
<b>处理autowireCandidate</b>:注解只有@Bean能指定该属性,如果false,则排除<br>
<font color="#ff0000"><b>处理泛型:</b></font>容器的bean类型有泛型参数时,匹配泛型参数和它的子类型(上确界)
<b>处理@Qualifier</b>
Qualifier, javax.inject.Qualifier注解都会处理,可以用在类或方法上
通过注点的@Qualifier和beanDefinition的@Qualifier的equals方法来判断是否相等,注解的equals是逻辑相等,所有成员相等即为相等<br>
bean定义上没有定义@Qualifier,则用beanName或别名来和注点匹配
找到候选者后,如果有多个,再找到@Primary,信息在beanDefinition中,如果有多个@Primary,报NoUniqueBeanDefinitionException
如果没有@Primary,找@Priority最小的
根据字段名称和beanName或者别名匹配
找到注入点的beanName后,beanFactory.getBean获取依赖对象