文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring populateBean属性赋值和自动注入的方法是什么

2023-07-05 12:37

关注

这篇文章主要介绍“Spring populateBean属性赋值和自动注入的方法是什么”,在日常操作中,相信很多人在Spring populateBean属性赋值和自动注入的方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Spring populateBean属性赋值和自动注入的方法是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

正文

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {   if (bw == null) {      if (mbd.hasPropertyValues()) {         throw new BeanCreationException(               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");      }      else {         // Skip property population phase for null instance.         return;      }   }   // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the   // state of the bean before properties are set. This can be used, for example,   // to support styles of field injection.   //一、修改Bean实例   //给InstantiationAwareBeanPostProcessors最后一个机会在属性设置前改变bean   // 具体通过调用ibp.postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {      for (BeanPostProcessor bp : getBeanPostProcessors()) {         if (bp instanceof InstantiationAwareBeanPostProcessor) {            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;            //返回值为true则继续填充bean            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {               return;            }         }      }   }   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);    // 根据bean的依赖注入方式:即是否标注有 @Autowired 注解或 autowire=“byType/byName” 的标签   // 会遍历bean中的属性,根据类型或名称来完成相应的注入   int resolvedAutowireMode = mbd.getResolvedAutowireMode();   if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);      // Add property values based on autowire by name if applicable.      //二、根据名称自动注入      if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {         autowireByName(beanName, mbd, bw, newPvs);      }      // Add property values based on autowire by type if applicable.      //三、根据类型自动注入      if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {         autowireByType(beanName, mbd, bw, newPvs);      }      pvs = newPvs;   }    // 容器是否注册了InstantiationAwareBeanPostProcessor   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();   // 是否进行依赖检查   boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);   PropertyDescriptor[] filteredPds = null;   if (hasInstAwareBpps) {      if (pvs == null) {         pvs = mbd.getPropertyValues();      }      for (BeanPostProcessor bp : getBeanPostProcessors()) {         if (bp instanceof InstantiationAwareBeanPostProcessor) {            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;            PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);            if (pvsToUse == null) {               if (filteredPds == null) {                  filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);               }               //对所有需要依赖检查的属性进行后处理               //四、处理属性值(@Autowired、@Value)               pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);               if (pvsToUse == null) {                  return;               }            }            pvs = pvsToUse;         }      }   }   // 检查是否满足相关依赖关系,对应的depends-on属性,3.0后已弃用   if (needsDepCheck) {      if (filteredPds == null) {         filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);      }      checkDependencies(beanName, mbd, filteredPds, pvs);   }   // 五、填充属性   if (pvs != null) {      applyPropertyValues(beanName, mbd, bw, pvs);   }}

一、postProcessAfterInstantiation:修改Bean实例

在填充属性之前调用postProcessAfterInstantiation修改Bean定义信息

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {   for (BeanPostProcessor bp : getBeanPostProcessors()) {      if (bp instanceof InstantiationAwareBeanPostProcessor) {         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;         if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {            return;         }      }   }}

二、autowireByName:根据名称自动注入

protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {    //寻找bw中需要依赖注入的属性    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);    for (String propertyName : propertyNames) {        //检查缓存bean中是否存在当前bean        if (containsBean(propertyName)) {            //递归初始化相关的bean. 代码(1)            Object bean = getBean(propertyName);            pvs.add(propertyName, bean);            //注册依赖            registerDependentBean(propertyName, beanName);            if (logger.isTraceEnabled()) {                logger.trace("Added autowiring by name from bean name '" + beanName +                        "' via property '" + propertyName + "' to bean named '" + propertyName + "'");            }        } else {            // 找不到则不处理            if (logger.isTraceEnabled()) {                logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +                        "' by name: no matching bean found");            }        }    }}

三、autowireByType:根据类型自动注入

protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {    // 获取自定义的类型转换器    TypeConverter converter = getCustomTypeConverter();    if (converter == null) {        converter = bw;    }    Set<String> autowiredBeanNames = new LinkedHashSet<>(4);    //寻找bw中需要依赖注入的属性    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);    for (String propertyName : propertyNames) {        try {            // 获取属性描述符            PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);            //不要尝试按类型为Object类型自动装配:即使从技术上讲是不满意的,非简单的属性,也没有意义。            if (Object.class != pd.getPropertyType()) {                //探测指定属性的set方法                MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);                // Do not allow eager init for type matching in case of a prioritized post-processor.                boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());                DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);                //解析指定beanName的属性所匹配的值,并把解析到的属性名称存储在autowiredBeanNames中,当属性存在多个封装bean时                //比如: @Autowired private List<A> aList; 就会找到所有匹配A类型的bean并将其注入                Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);                if (autowiredArgument != null) {                    // 添加到待注入的bean列表中                    pvs.add(propertyName, autowiredArgument);                }                for (String autowiredBeanName : autowiredBeanNames) {                    //注册依赖                    registerDependentBean(autowiredBeanName, beanName);                    if (logger.isTraceEnabled()) {                        logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +                                propertyName + "' to bean named '" + autowiredBeanName + "'");                    }                }                autowiredBeanNames.clear();            }        } catch (BeansException ex) {            throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);        }    }}

四、postProcessPropertyValues:处理属性值(@Resource、@Autowired、@Value)

CommonAnnotationBeanPostProcessor:处理@Resource

AutowiredAnnotationBeanPostProcessor:处理@Autowired、@Value。

详情:https://www.yisu.com/article/277330.htm

五、applyPropertyValues:填充属性

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {    if (pvs.isEmpty()) {        return;    }    if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {        ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());    }    MutablePropertyValues mpvs = null;    List<PropertyValue> original;    if (pvs instanceof MutablePropertyValues) {        mpvs = (MutablePropertyValues) pvs;        //如果mpvs中的值已经被转换为对应的类型那么可以直接设置到beanWrapper        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;    }    //获取对应的解析器    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);    // Create a deep copy, resolving any references for values.    List<PropertyValue> 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();            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);    }}

解析、注入值

public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {    // We must check each value to see whether it requires a runtime reference    // to another bean to be resolved.    // 5.1 解析引用    if (value instanceof RuntimeBeanReference) {        RuntimeBeanReference ref = (RuntimeBeanReference) value;        return resolveReference(argName, ref);    }    // 如果根据另一个Bean的name进行依赖,进入下面的分支    else if (value instanceof RuntimeBeanNameReference) {        String refName = ((RuntimeBeanNameReference) value).getBeanName();        refName = String.valueOf(doEvaluate(refName));        if (!this.beanFactory.containsBean(refName)) {            throw new BeanDefinitionStoreException(                    "Invalid bean name '" + refName + "' in bean reference for " + argName);        }        return refName;    }    // 解析BeanDefinitionHolder    else if (value instanceof BeanDefinitionHolder) {        // Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.        BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;        return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());    }    // 解析纯BeanDefinition    else if (value instanceof BeanDefinition) {        // Resolve plain BeanDefinition, without contained name: use dummy name.        BeanDefinition bd = (BeanDefinition) value;        String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +                ObjectUtils.getIdentityHexString(bd);        return resolveInnerBean(argName, innerBeanName, bd);    }    // 解析数组    else if (value instanceof ManagedArray) {        // May need to resolve contained runtime references.        ManagedArray array = (ManagedArray) value;        Class<?> elementType = array.resolvedElementType;        if (elementType == null) {            String elementTypeName = array.getElementTypeName();            if (StringUtils.hasText(elementTypeName)) {                try {                    elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());                    array.resolvedElementType = elementType;                }                catch (Throwable ex) {                    // Improve the message by showing the context.                    throw new BeanCreationException(                            this.beanDefinition.getResourceDescription(), this.beanName,                            "Error resolving array type for " + argName, ex);                }            }            else {                elementType = Object.class;            }        }        return resolveManagedArray(argName, (List<?>) value, elementType);    }    //5.2解析List    else if (value instanceof ManagedList) {        // May need to resolve contained runtime references.        return resolveManagedList(argName, (List<?>) value);    }    // 解析Set    else if (value instanceof ManagedSet) {        // May need to resolve contained runtime references.        return resolveManagedSet(argName, (Set<?>) value);    }    // 解析Map    else if (value instanceof ManagedMap) {        // May need to resolve contained runtime references.        return resolveManagedMap(argName, (Map<?, ?>) value);    }    // 解析Properties    else if (value instanceof ManagedProperties) {        Properties original = (Properties) value;        Properties copy = new Properties();        original.forEach((propKey, propValue) -> {            if (propKey instanceof TypedStringValue) {                propKey = evaluate((TypedStringValue) propKey);            }            if (propValue instanceof TypedStringValue) {                propValue = evaluate((TypedStringValue) propValue);            }            if (propKey == null || propValue == null) {                throw new BeanCreationException(                        this.beanDefinition.getResourceDescription(), this.beanName,                        "Error converting Properties key/value pair for " + argName + ": resolved to null");            }            copy.put(propKey, propValue);        });        return copy;    }    // 解析String    else if (value instanceof TypedStringValue) {        // Convert value to target type here.        TypedStringValue typedStringValue = (TypedStringValue) value;        Object valueObject = evaluate(typedStringValue);        try {            Class<?> resolvedTargetType = resolveTargetType(typedStringValue);            if (resolvedTargetType != null) {                return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);            }            else {                return valueObject;            }        }        catch (Throwable ex) {            // Improve the message by showing the context.            throw new BeanCreationException(                    this.beanDefinition.getResourceDescription(), this.beanName,                    "Error converting typed String value for " + argName, ex);        }    }    else if (value instanceof NullBean) {        return null;    }    else {        return evaluate(value);    }}

5.1 解析依赖

核心还是getBean方法!开始触发关联创建Bean

private Object resolveReference(Object argName, RuntimeBeanReference ref) {    try {        Object bean;        // 获取BeanName        String refName = ref.getBeanName();        refName = String.valueOf(doEvaluate(refName));        // 如果Bean在父容器,则去父容器取        if (ref.isToParent()) {            if (this.beanFactory.getParentBeanFactory() == null) {                throw new BeanCreationException(                        this.beanDefinition.getResourceDescription(), this.beanName,                        "Can't resolve reference to bean '" + refName +                                "' in parent factory: no parent factory available");            }            bean = this.beanFactory.getParentBeanFactory().getBean(refName);        }        else {            // 在本容器,调用getBean            bean = this.beanFactory.getBean(refName);            this.beanFactory.registerDependentBean(refName, this.beanName);        }        if (bean instanceof NullBean) {            bean = null;        }        return bean;    }    catch (BeansException ex) {        throw new BeanCreationException(                this.beanDefinition.getResourceDescription(), this.beanName,                "Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);    }}

5.2 解析List

直接把 List 集合塞入属性中即可。

private List<?> resolveManagedList(Object argName, List<?> ml) {    List<Object> resolved = new ArrayList<>(ml.size());    for (int i = 0; i < ml.size(); i++) {        resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));    }    return resolved;}

到此,关于“Spring populateBean属性赋值和自动注入的方法是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯