SpringloC容器的依赖注入源码解析(10)—— populateBean的剩余逻辑(1)

}

}

该方法遍历每一个属性元素去调用元素的inject方法,进入inject发现又回到了AutowiredAnnotationBeanPostProcessor类里:

@Override

protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {

// 获取要注入的成员变量

Field field = (Field) this.member;

Object value;

// 如果成员变量的值先前缓存过

if (this.cached) {

// 从缓存中获取成员变量的值

value = resolvedCachedArgument(beanName, this.cachedFieldValue);

}

// 没有缓存

else {

// 创建一个成员变量的依赖描述符实例

DependencyDescriptor desc = new DependencyDescriptor(field, this.required);

desc.setContainingClass(bean.getClass());

Set autowiredBeanNames = new LinkedHashSet<>(1);

Assert.state(beanFactory != null, “No BeanFactory available”);

// 获取容器的类型转换器

TypeConverter typeConverter = beanFactory.getTypeConverter();

try {

// 获取注入的值

value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);

}

catch (BeansException ex) {

throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);

}

synchronized (this) {

if (!this.cached) {

if (value != null || this.required) {

this.cachedFieldValue = desc;

registerDependentBeans(beanName, autowiredBeanNames);

if (autowiredBeanNames.size() == 1) {

String autowiredBeanName = autowiredBeanNames.iterator().next();

if (beanFactory.containsBean(autowiredBeanName) &&

beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {

this.cachedFieldValue = new ShortcutDependencyDescriptor(

desc, autowiredBeanName, field.getType());

}

}

}

else {

this.cachedFieldValue = null;

}

this.cached = true;

}

}

}

if (value != null) {

ReflectionUtils.makeAccessible(field);

field.set(bean, value);

}

}

}

在调用的过程中复用了其他类的装配能力,此时是给boyfriend装配上girlfriend实例,首先去缓存里看下之前是否解析过girlfriend,第一次执行会进入到else里,先用DependencyDescriptor包装一下属性field

DependencyDescriptor desc = new DependencyDescriptor(field, this.required);

之后给desc注册上宿主的类名(Boyfriend):

desc.setContainingClass(bean.getClass());

之后会尝试获取之前容器初始化时注册上去的转换器TypeConverter

TypeConverter typeConverter = beanFactory.getTypeConverter();

converter用来做类型转换,默认获取spring自带的simpleTypeConverter用来处理简单类型的转换,之后执行

// 获取注入的值

value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);

进入resolveDependency方法里:

@Override

@Nullable

public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,

@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());

if (Optional.class == descriptor.getDependencyType()) {

return createOptionalDependency(descriptor, requestingBeanName);

}

else if (ObjectFactory.class == descriptor.getDependencyType() ||

ObjectProvider.class == descriptor.getDependencyType()) {

return new DependencyObjectProvider(descriptor, requestingBeanName);

}

else if (javaxInjectProviderClass == descriptor.getDependencyType()) {

return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);

}

else {

Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(

descriptor, requestingBeanName);

if (result == null) {

result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);

}

return result;

}

}

在方法里会依据依赖描述符的不同类型进行不同的处理,但是最终都会到else里,真正起作用的是doResolveDependency方法

@Nullable

public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,

@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);

try {

// 该方法最终调用了beanFactory.getBean(String, Class),从容器中获取依赖

Object shortcut = descriptor.resolveShortcut(this);

// 如果容器缓存中存在所需依赖,这里进行短路路操作,提前结束依赖解析逻辑

if (shortcut != null) {

return shortcut;

}

Class<?> type = descriptor.getDependencyType();

// 处理@Value注解

Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);

if (value != null) {

if (value instanceof String) {

String strVal = resolveEmbeddedValue((String) value);

BeanDefinition bd = (beanName != null && containsBean(beanName) ?

getMergedBeanDefinition(beanName) : null);

value = evaluateBeanDefinitionString(strVal, bd);

}

TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());

try {

return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());

}

catch (UnsupportedOperationException ex) {

// A custom TypeConverter which does not support TypeDescriptor resolution…

return (descriptor.getField() != null ?

converter.convertIfNecessary(value, type, descriptor.getField()) :

converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));

}

}

// 如果标识@Autowired注解的成员变量是复合类型,如Array,Collection,Map

// 从这个方法获取@Autowired里的值

Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);

if (multipleBeans != null) {

return multipleBeans;

}

Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);

if (matchingBeans.isEmpty()) {

if (isRequired(descriptor)) {

raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);

}

return null;

}

String autowiredBeanName;

Object instanceCandidate;

if (matchingBeans.size() > 1) {

autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);

if (autowiredBeanName == null) {

if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {

return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);

}

else {

// In case of an optional Collection/Map, silently ignore a non-unique case:

// possibly it was meant to be an empty collection of multiple regular beans

// (before 4.3 in particular when we didn’t even look for collection beans).

return null;

}

}

instanceCandidate = matchingBeans.get(autowiredBeanName);

}

else {

// We have exactly one match.

Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();

autowiredBeanName = entry.getKey();

instanceCandidate = entry.getValue();

}

if (autowiredBeanNames != null) {

autowiredBeanNames.add(autowiredBeanName);

}

if (instanceCandidate instanceof Class) {

instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);

}

Object result = instanceCandidate;

if (result instanceof NullBean) {

if (isRequired(descriptor)) {

raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);

}

result = null;

}

if (!ClassUtils.isAssignableValue(type, result)) {

throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());

}

return result;

}

finally {

ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);

}

}

首先尝试调用依赖描述符实例的resolveShortcut方法,尝试从容器缓存里获取属性名对应的bean实例

@Nullable

public Object resolveShortcut(BeanFactory beanFactory) throws BeansException {

return null;

}

相对于注解的这种情况,并没有实现该方法。


之后尝试从依赖描述符实例里面去获取目标实例的属性

Class<?> type = descriptor.getDependencyType();

这里的目标实例是girlfriend,之后就会调用注解候选解析器的getSuggestedValue方法尝试获取属性值,但是对于@Autowired修饰的属性来说,这一步无法获取到值

@Override

@Nullable

public Object getSuggestedValue(DependencyDescriptor descriptor) {

Object value = findValue(descriptor.getAnnotations());

if (value == null) {

MethodParameter methodParam = descriptor.getMethodParameter();

if (methodParam != null) {

value = findValue(methodParam.getMethodAnnotations());

}

}

return value;

}

该方法调用findValue方法

@Nullable

protected Object findValue(Annotation[] annotationsToSearch) {

if (annotationsToSearch.length > 0) { // qualifier annotations have to be local

AnnotationAttributes attr = AnnotatedElementUtils.getMergedAnnotationAttributes(

AnnotatedElementUtils.forAnnotations(annotationsToSearch), this.valueAnnotationType);

if (attr != null) {

return extractValue(attr);

}

}

return null;

}

该方法主要是提取@Value修饰的属性值的


回到doResolveDependency方法

请添加图片描述

在if里会视情况对获取到的value进行类型转换。

之后来到resolveMultipleBeans方法

// 如果标识@Autowired注解的成员变量是复合类型,如Array,Collection,Map

// 从这个方法获取@Autowired里的值

Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);

@Nullable

private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,

@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) {

final Class<?> type = descriptor.getDependencyType();

// 首先是stream类型的处理

if (descriptor instanceof StreamDependencyDescriptor) {

Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);

if (autowiredBeanNames != null) {

autowiredBeanNames.addAll(matchingBeans.keySet());

}

Stream stream = matchingBeans.keySet().stream()

.map(name -> descriptor.resolveCandidate(name, type, this))

.filter(bean -> !(bean instanceof NullBean));

if (((StreamDependencyDescriptor) descriptor).isOrdered()) {

stream = stream.sorted(adaptOrderComparator(matchingBeans));

}

return stream;

}

// 判断要注入的是不是一个数组,可见除了集合注入外,也可以以数组的形式注入bean

else if (type.isArray()) {

Class<?> componentType = type.getComponentType();

ResolvableType resolvableType = descriptor.getResolvableType();

Class<?> resolvedArrayType = resolvableType.resolve(type);

if (resolvedArrayType != type) {

componentType = resolvableType.getComponentType().resolve();

}

if (componentType == null) {

return null;

}

Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,

new MultiElementDescriptor(descriptor));

if (matchingBeans.isEmpty()) {

return null;

}

if (autowiredBeanNames != null) {

autowiredBeanNames.addAll(matchingBeans.keySet());

}

TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());

Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);

if (result instanceof Object[]) {

Comparator comparator = adaptDependencyComparator(matchingBeans);

if (comparator != null) {

Arrays.sort((Object[]) result, comparator);

}

}

return result;

}

// 判断注入的是不是集合的接口类(List,Set等)

else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {

Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();

if (elementType == null) {

return null;

}

Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,

new MultiElementDescriptor(descriptor));

if (matchingBeans.isEmpty()) {

return null;

}

if (autowiredBeanNames != null) {

autowiredBeanNames.addAll(matchingBeans.keySet());

}

TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());

Object result = converter.convertIfNecessary(matchingBeans.values(), type);

if (result instanceof List) {

Comparator comparator = adaptDependencyComparator(matchingBeans);

if (comparator != null) {

((List<?>) result).sort(comparator);

}

}

return result;

}

// 判断要注入的是不是map类

else if (Map.class == type) {

ResolvableType mapType = descriptor.getResolvableType().asMap();

Class<?> keyType = mapType.resolveGeneric(0);

if (String.class != keyType) {

return null;

}

Class<?> valueType = mapType.resolveGeneric(1);

if (valueType == null) {

return null;

}

Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,

new MultiElementDescriptor(descriptor));

if (matchingBeans.isEmpty()) {

return null;

}

if (autowiredBeanNames != null) {

autowiredBeanNames.addAll(matchingBeans.keySet());

}

return matchingBeans;

}

else {

return null;

}

}

该方法主要是针对复合类型(stream类型、数组类型、集合类型、map类型)的值进行解析处理,无论是哪种复合类型,最终都会调用findAutowireCandidates方法去获取注入的候选者列表(可能有多个)

由于测试时并非用的复合类型的数据,所以此处的multipleBeans为空


回到doResolveDependency,继续执行后续的逻辑

// 如果标识@Autowired注解的属性是非复合类型

// 从这个方法获取@Autowired里的值

Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);

if (matchingBeans.isEmpty()) {

// 没有找到,检验@Autowire的require是否为true

if (isRequired(descriptor)) {

raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);

}

return null;

}

处理被@Autowired标记的非复合类型的逻辑,同样会调用处理复合逻辑类型里的findAutowireCandidates方法尝试从容器里面根据属性的类型获取到对应的bean名字,

protected Map<String, Object> findAutowireCandidates(

@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {

// 查找出所有符合类型的beanName

String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(

this, requiredType, true, descriptor.isEager());

Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);

// resolvableDependencies记录了属性类型–值的映射

for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {

Class<?> autowiringType = classObjectEntry.getKey();

if (autowiringType.isAssignableFrom(requiredType)) {

Object autowiringValue = classObjectEntry.getValue();

// key值是我们需要的类型

autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);

if (requiredType.isInstance(autowiringValue)) {

result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);

break;

}

}

}

// 遍历候选数组

for (String candidate : candidateNames) {

// 候选Bean不是自引用(即要注入的类不能是类本身,会触发无限递归注入)

if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {

addCandidateEntry(result, candidate, descriptor, requiredType);

}

}

if (result.isEmpty()) {

boolean multiple = indicatesMultipleBeans(requiredType);

// Consider fallback matches if the first pass failed to find anything…

DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();

for (String candidate : candidateNames) {

if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&

(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {

addCandidateEntry(result, candidate, descriptor, requiredType);

}

}

if (result.isEmpty() && !multiple) {

// Consider self references as a final pass…

// but in the case of a dependency collection, not the very same bean itself.

for (String candidate : candidateNames) {

if (isSelfReference(beanName, candidate) &&

(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&

isAutowireCandidate(candidate, fallbackDescriptor)) {

addCandidateEntry(result, candidate, descriptor, requiredType);

}

}

}

}

return result;

}

首先调用BeanFactoryUtils.beanNamesForTypeIncludingAncestors,尝试获取针对于该属性的候选名单,beanNamesForTypeIncludingAncestors会尝试从各层容器里寻找符合该属性类型的bean的名字。

Map<String, Object> result会存放girlfriend。

之后会尝试去从已经注册到容器里的依赖关系里,去寻找先前有没有注入过girlfriend属性的依赖,这里相当于缓存的作用,由于是第一次所以肯定没有。

之后for循环会轮询候选列表做一些必要的检查,过滤掉自己依赖于自己的,再看看是否是支持注入的,满足条件就将其添加到候选人的列表当中

之后如果result为空的话会对依赖描述符做一个降级处理(一般进不来这个逻辑里)

DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();

这一步可以理解为在容器里找不到和当前类型匹配的bean时,会尝试去到可以替代该类的类中查找,比如girlfriend的父类看看能不能找到候选者


回到doResolveDependency,如果选出的bean个数大于1的话,就会选出最佳的候选者

if (matchingBeans.size() > 1) {

// 如果被@Autowired标记的有两个以上同样的类型。

// 就需要依据@Primary以及@Priority注解标签选择了

autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);

if (autowiredBeanName == null) {

if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {

// 无法选出唯一的,则直接报错

return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);

}

else {

// In case of an optional Collection/Map, silently ignore a non-unique case:

// possibly it was meant to be an empty collection of multiple regular beans

// (before 4.3 in particular when we didn’t even look for collection beans).

return null;

}

}

instanceCandidate = matchingBeans.get(autowiredBeanName);

}

进入到determineAutowireCandidate方法,用于选择最佳的候选bean:

@Nullable

protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {

Class<?> requiredType = descriptor.getDependencyType();

// 根据@Primary注解标签来选择最优解

String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);

if (primaryCandidate != null) {

return primaryCandidate;

}

// 根据@Order,@PriorityOrder,及实现Order接口的序号来选择最优解,选序号最小的

String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);

if (priorityCandidate != null) {

return priorityCandidate;

}

// Fallback

for (Map.Entry<String, Object> entry : candidates.entrySet()) {

String candidateName = entry.getKey();

Object beanInstance = entry.getValue();

if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||

matchesBeanName(candidateName, descriptor.getDependencyName())) {

return candidateName;

}

}

return null;

}

  1. 先找候选bean里是否有被@Primary标记的,有则直接选择;

  2. 没有的话再据@Order,@PriorityOrder,及实现Order接口的序号来选择最优解,选序号最小的;

  3. 没有的话降级看看有没有合适的bean,用属性的名字或别名找有没有相关的bean返回。

从上面的逻辑可以看出,@Autowired并非一定按照类型来查找。


回到doResolveDependency,由于在我们的例子里只有一个候选者,所以会来到else

else {

// We have exactly one match.

Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();

autowiredBeanName = entry.getKey();

instanceCandidate = entry.getValue();

}

在这里会获取到对应的属性名,以及属性对应的class对象,此时只是拿到了girlfriend的名字和class,还没有创建出其实例,因为在最终确认之前没必要创建多余的bean实例。

之后调用resolveCandidate去解析类的实例:

if (instanceCandidate instanceof Class) {

instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);

}

public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)

throws BeansException {

return beanFactory.getBean(beanName);

}

所谓的解析其实就是根据bean的名字去调用容器的getBean方法去获取/创建出bean实例,如果经过aop包装的话,获取出的属性也会是经过aop包装的。

剩下后续就是一些验证了逻辑了,验证完之后就执行完成整个doResolveDependency方法了,此时resolveDependency方法就获得了girlfriend对应的bean实例了,再上一层回到AutowiredAnnotationBeanPostProcessor的inject方法执行的地方,获取到girlfriend的bean实例之后,就会去注册相关的依赖关系

在这里插入图片描述

synchronized (this) {

if (!this.cached) {

// 成员变量的值不为null,并且required属性为true

if (value != null || this.required) {

this.cachedFieldValue = desc;

// 为指定Bean注册依赖Bean

registerDependentBeans(beanName, autowiredBeanNames);

if (autowiredBeanNames.size() == 1) {

String autowiredBeanName = autowiredBeanNames.iterator().next();

// 如果容器中有指定名称的Bean对象

if (beanFactory.containsBean(autowiredBeanName) &&

// 依赖对象类型和字段类型匹配,默认按类型注入

beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {

this.cachedFieldValue = new ShortcutDependencyDescriptor(

desc, autowiredBeanName, field.getType());

}

}

}

else {

this.cachedFieldValue = null;

}

this.cached = true;

}

}

注册完依赖关系后就会将bean实例放入到缓存里,在inject方法最后就是调用反射机制来给field设置上该bean实例了

// 如果字段值不为null

if (value != null) {

// 使用反射机制来赋值

ReflectionUtils.makeAccessible(field);

field.set(bean, value);

}


之后回到AbstractAutowireCapableBeanFactory的populateBean方法

// 在这里会对@Autowired标记的属性进行依赖注入

PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);

这时这里执行完毕了,boyfriend就会设置上girlfriend的bean实例,接下来来到依赖检查,

// 依赖检查,对应depend-on属性,3.0已经弃用此属性

if (needsDepCheck) {

// 过滤出所有需要进行依赖检查的属性编辑器

if (filteredPds == null) {

filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

}

checkDependencies(beanName, mbd, filteredPds, pvs);

}

这里是对显式指定depends-on来检查的,默认不开启,所以会来到

if (pvs != null) {

// 最终将属性注入到Bean的Wrapper实例里,这里的注入主要是供

// 显式配置了autowiredbyName或者ByType的属性注入,

// 针对注解来讲,由于在AutowiredAnnotationBeanPostProcessor已经完成了注入,

// 所以此处不执行

applyPropertyValues(beanName, mbd, bw, pvs);

}

进入到applyPropertyValues方法里:

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {

if (pvs.isEmpty()) {

return;

}

if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {

// 设置安全上下文,JDK安全机制

((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());

}

MutablePropertyValues mpvs = null;

List original;

if (pvs instanceof MutablePropertyValues) {

mpvs = (MutablePropertyValues) pvs;

if (mpvs.isConverted()) {

// Shortcut: use the pre-converted values as-is.

// 若属性值已经转换了,则直接赋值

try {

bw.setPropertyValues(mpvs);

return;

}

catch (BeansException ex) {

throw new BeanCreationException(

mbd.getResourceDescription(), beanName, “Error setting property values”, ex);

}

}

// 若没有被转换,先将没转换前的原始类型值给记录下来

original = mpvs.getPropertyValueList();

}

else {

// 如果pvs不是MutablePropertyValues类型,则直接使用原始类型

original = Arrays.asList(pvs.getPropertyValues());

}

// 获取用户的自定义类型转换

TypeConverter converter = getCustomTypeConverter();

if (converter == null) {

converter = bw;

}

// 创建一个Bean定义属性值解析器,将BeanDefinition中的属性值解析为Bean实例对象的实际值

BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

// Create a deep copy, resolving any references for values.

// 为属性需要解析的值创建一个副本,将副本的数据注入Bean实例

List deepCopy = new ArrayList<>(original.size());

boolean resolveNecessary = false;

for (PropertyValue pv : original) {

// 不需要转换的属性值直接添加

if (pv.isConverted()) {

deepCopy.add(pv);

}

else {

String propertyName = pv.getName();

// 保留转换前的属性值

Object originalValue = pv.getValue();

// 如果是被Autowired标记的实例,则把Bean里面关于set此属性的方法给记录下来,

if (originalValue == AutowiredPropertyMarker.INSTANCE) {

Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();

if (writeMethod == null) {

throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);

}

originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);

}

Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);

Object convertedValue = resolvedValue;

boolean convertible = bw.isWritableProperty(propertyName) &&

!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);

if (convertible) {

convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);

}

// Possibly store converted value in merged bean definition,

// in order to avoid re-conversion for every created bean instance.

if (resolvedValue == originalValue) {

if (convertible) {

pv.setConvertedValue(convertedValue);

}

deepCopy.add(pv);

}

else if (convertible && originalValue instanceof TypedStringValue &&

!((TypedStringValue) originalValue).isDynamic() &&

!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {

pv.setConvertedValue(convertedValue);

deepCopy.add(pv);

}

else {

resolveNecessary = true;

deepCopy.add(new PropertyValue(pv, convertedValue));

}

}

}

if (mpvs != null && !resolveNecessary) {

mpvs.setConverted();

}

// Set our (possibly massaged) deep copy.

try {

// 进行属性的依赖注入

bw.setPropertyValues(new MutablePropertyValues(deepCopy));

}

catch (BeansException ex) {

throw new BeanCreationException(

mbd.getResourceDescription(), beanName, “Error setting property values”, ex);

}

}

针对注解的情况,直接返回

if (pvs.isEmpty()) {

return;

}

该方法主要是视情况做各种属性值的类型转换,毕竟获取到的是字符串类型的Type,需要这些字符串的type转换成对应的类型,首先看一下缓存里有没有,如果没有再做转换,转换完成后最终会调用
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

Java架构学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。

还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书+2021年最新大厂面试题。
在这里插入图片描述

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
Value));

}

}

}

if (mpvs != null && !resolveNecessary) {

mpvs.setConverted();

}

// Set our (possibly massaged) deep copy.

try {

// 进行属性的依赖注入

bw.setPropertyValues(new MutablePropertyValues(deepCopy));

}

catch (BeansException ex) {

throw new BeanCreationException(

mbd.getResourceDescription(), beanName, “Error setting property values”, ex);

}

}

针对注解的情况,直接返回

if (pvs.isEmpty()) {

return;

}

该方法主要是视情况做各种属性值的类型转换,毕竟获取到的是字符串类型的Type,需要这些字符串的type转换成对应的类型,首先看一下缓存里有没有,如果没有再做转换,转换完成后最终会调用
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-gbNeTtSr-1713420248515)]

[外链图片转存中…(img-8wiiIhe3-1713420248516)]

[外链图片转存中…(img-YIrNEtZt-1713420248516)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

Java架构学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。

还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书+2021年最新大厂面试题。
[外链图片转存中…(img-Qrk3kYtO-1713420248516)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值