003-依赖注入、属性赋值源码分析
目录
引入
之前我们了解到BeanDefinition到Bean,经历了
- 实例化
- 属性赋值
- 初始化
3个步骤现在详细分析下属性赋值:populateBean(beanName, mbd, instanceWrapper);
作用
就是查找Bean内字段或者方法上是否有@Autowired
如果有则从 context中查找并赋值,完成依赖注入
代码分析
其实就是解析各种依赖存入 getPropertyValues 缓存(相当于一个Map)
最后在统一反射到属性中
beanName – the name of the bean
mbd – the bean definition for the bean
bw – the BeanWrapper with bean instance
populateBean(beanName, mbd, instanceWrapper);
ropertyValues pvs = mbd.getPropertyValues();
//可以这样设置@Bean(autowire = Autowire.BY_NAME)
//这里只是解析 但是并没有真的设置 设值在最后一行
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || AUTOWIRE_BY_TYPE) {
创建一个缓存 newPvs
//意思是Bean的属性注入自动根据其Setter的名字或者属性
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
newPvs.put(属性的名字(propertyName), getBean(propertyName));
}
//也可以 Autowire.BY_TYPE 就是根据Setter 参数的类型
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
newPvs.put(属性的名字(propertyName), getBean(属性Setter的参数的类型));
}
pvs = newPvs;
}
//注意:这个方式已经被标记为过时的 因为这样调试起来很麻烦 而且不是很方便推荐还是@Autowired
遍历处理器 InstantiationAwareBeanPostProcessor bp {
pvs = bp.postProcessProperties();
}
//根据pvs给对象设值
if (pvs != null) {
//这里最终也是通过反射把值设置到字段中BeanWrapperImpl.BeanPropertyHandler#setValue
applyPropertyValues(beanName, mbd, bw, pvs);
}
InstantiationAwareBeanPostProcessor#postProcessProperties()
这个处理器就是用来专门处理Bean的属性的
AutowiredAnnotationBeanPostProcessor
这个处理器实现就是专门处理@Autowired之类的逻辑
初始化的时候autowiredAnnotationTypes设置了
- Autowired.class
- Value.class
- javax.inject.Inject
postProcessProperties():
//查找注入点元数据
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
//给注入点注入属性
metadata.inject(bean, beanName, pvs);
查找注入点元数据
findAutowiringMetadata():
//这里metadata 其实已经有值了
//在 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
//其实就进入了AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
//在buildAutowiringMetadata()就把带注解的字段和方法解析完了
//并设置到injectedElements字段中
//最后 this.injectionMetadataCache.put(cacheKey, new InjectionMetadata(clazz, injectedElements)));
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (metadata == null) {
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(beanName, );
}
//这里就是构建元数据
//构建元数据的前提是有需要注入的点 如果有则创建一个AutowiredFieldElement加入currElements
buildAutowiringMetadata(clazz):
遍历所有的字段(field) {
if(带有4个注解之一) {
currElements.add(new AutowiredFieldElement(field, required));
}
}
遍历所有方法(method){
if(带有4个注解之一) {
PropertyDescriptor pd = 这个方法是否是某个字段的读写
currElements.add(new AutowiredMethodElement(method, required, pd));
}
}
return new InjectionMetadata(currElements, clazz);
给注入点注入属性
AutowiredFieldElement#inject
//找到字段的值
value = resolveFieldValue(field, bean, beanName);
//反射
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
resolveFieldValue(field, bean, beanName):
//包装成统一的描述符
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
//找到值
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
return value;
resolveDependency(desc, beanName, autowiredBeanNames, typeConverter):
//设置参数Name发现器
//1. -parameters java8 编译带了这个参数就能获取参数的name
//2. 本地变量表 基于ASM技术
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (类型不是 ObjectFactory || Optional) {
if(依赖带有@Lazy) {
return 对名称和依赖进行代理(在用的时候再查找注入);
}
return doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter):
if (descriptor储存了快速解析出来的对象) {
return shortcut;
}
Object value = 查找依赖是否有@Value, 并获取值
if (value != null && value instanceof String) {
//解析 ${} 配置内容并获取值
//计算解析不到也把#Value的值读取出来 后续el表达式解析
String strVal = resolveEmbeddedValue((String) value);
value = evaluateBeanDefinitionString(strVal, bd);
return 类型转化(value);
}
//这里就是判断依赖是否是复数的 下边的Object只是指代对象 不是特定的类型
//Map<String, Object> 会注入 BeanName : 符合要求的Bean对象 作为map的entry
//List<Object> 和 Object[] 会直接注入符合要求的所有Bean对象
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
//根据类型查找所有的符合要求的实例
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans 为空) {
if (isRequired) {
throw new NoSuchBeanDefinitionException()
}
return null;
}
//确定依赖的实例和名称
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
throw new NoUniqueBeanDefinitionException();
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
} else {
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
Object result = instanceCandidate;
//这个就是自己@Bean方法返回null 就会被处理成 NullBean 这样不需要到处判空
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
throw new NoSuchBeanDefinitionException();
}
result = null;
}
//确定是否符合要求的类型 在getBean(beanName, Class)方法中
//第二个参数就是用来在这里做校验的 会判断找出的实例类型是否符合要求
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException();
}
return result;
findAutowireCandidates(beanName, requiredType, dependencyDescriptor):
Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);
//根据类型获取所有的 候选名称
//其实就是 beanFactory中
//遍历 this.beanDefinitionNames 获取name mergedBeanDefinitions.get(beanName) 获取 RootBeanDefinition
//其中 RootBeanDefinition 是用来提前判断是否符合要求
//matchFound = isTypeMatch(beanName, requiredType, true);
//matchFound == trur 就符合要求
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
判断 resolvableDependencies 中是否有符合requiredType的对象
遍历 candidateNames {
if(不是自依赖 && isAutowireCandidate(candidate, descriptor)) {
candidates.put(candidateName, getSingleton(beanName, false).getClass());
}
}
//再次判断一下是否符合要求
isAutowireCandidate(candidate, descriptor) :
if (候选Definition.isAutowireCandidate() && 依赖的类型是一个 class) {
match = true;
//检查 @Qualifier 没配置返回true
match = checkQualifiers(bdHolder, dependencyType.getType() instanceof Class);
if (match)) {
//检查 @Qualifier 没配置返回true
match = checkQualifiers(bdHolder, descriptor.getMethodAnnotations();
}
return match;
}
//在查找到多个 候选实例的时候 确定一个最终的实例
determineAutowireCandidate(matchingBeans, descriptor):
String primaryBeanName;
//解析 @Primary
遍历 candidates : candidateBeanName{
if (有@Primary) {
if (primaryBeanName != null) {
throw new NoUniqueBeanDefinitionException();
}
primaryBeanName = candidateBeanName;
}
}
if (primaryBeanName != null) {
return primaryBeanName;
}
//解析 @javax.annotation.Priority
Integer highestPriority = null;
遍历 candidates : candidateBeanName{
if (有@javax.annotation.Priority) {
Integer thisPriority = Priority(value);
if (thisPriority == null) {
continue;
}
if (highestPriority != null && highestPriority == thisPriority ) {
throw new NoUniqueBeanDefinitionException();
}
if (highestPriority == null || highestPriority < thisPriority ) {
highestPriority = thisPriority;
primaryBeanName = candidateBeanName;
}
}
}
if (primaryBeanName != null) {
return primaryBeanName;
}
遍历 candidates : candidateBeanName{
//这个缓存里有4个可直接解析的实例
//{Class@501}"interface org.springframework.core.io.ResourceLoader" -> {AnnotationConfigApplicationContext@1779}
//{Class@508}"interface org.springframework.context.ApplicationEventPublisher" -> {AnnotationConfigApplicationContext@1779}
//{Class@510}"interface org.springframework.context.ApplicationContext" -> {AnnotationConfigApplicationContext@1779}
//{Class@504}"interface org.springframework.beans.factory.BeanFactory" -> {DefaultListableBeanFactory@1475}
if (this.resolvableDependencies.containsValue(beanInstance)) {
return candidateName;
}
//这里就是判断字段或者参数名称 是否和BeanName一致
if (matchesBeanName(candidateName, descriptor.getDependencyName()) {
return candidateName;
}
}