经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
Spring?populateBean属性赋值和自动注入
来源:jb51  时间:2023/3/15 8:52:41  对本文有异议

正文

  1. protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
  2. if (bw == null) {
  3. if (mbd.hasPropertyValues()) {
  4. throw new BeanCreationException(
  5. mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
  6. }
  7. else {
  8. // Skip property population phase for null instance.
  9. return;
  10. }
  11. }
  12. // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
  13. // state of the bean before properties are set. This can be used, for example,
  14. // to support styles of field injection.
  15. //一、修改Bean实例
  16. //给InstantiationAwareBeanPostProcessors最后一个机会在属性设置前改变bean
  17. // 具体通过调用ibp.postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
  18. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  19. for (BeanPostProcessor bp : getBeanPostProcessors()) {
  20. if (bp instanceof InstantiationAwareBeanPostProcessor) {
  21. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
  22. //返回值为true则继续填充bean
  23. if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
  24. return;
  25. }
  26. }
  27. }
  28. }
  29. PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
  30. // 根据bean的依赖注入方式:即是否标注有 @Autowired 注解或 autowire=“byType/byName” 的标签
  31. // 会遍历bean中的属性,根据类型或名称来完成相应的注入
  32. int resolvedAutowireMode = mbd.getResolvedAutowireMode();
  33. if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
  34. MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
  35. // Add property values based on autowire by name if applicable.
  36. //二、根据名称自动注入
  37. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
  38. autowireByName(beanName, mbd, bw, newPvs);
  39. }
  40. // Add property values based on autowire by type if applicable.
  41. //三、根据类型自动注入
  42. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
  43. autowireByType(beanName, mbd, bw, newPvs);
  44. }
  45. pvs = newPvs;
  46. }
  47. // 容器是否注册了InstantiationAwareBeanPostProcessor
  48. boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
  49. // 是否进行依赖检查
  50. boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
  51. PropertyDescriptor[] filteredPds = null;
  52. if (hasInstAwareBpps) {
  53. if (pvs == null) {
  54. pvs = mbd.getPropertyValues();
  55. }
  56. for (BeanPostProcessor bp : getBeanPostProcessors()) {
  57. if (bp instanceof InstantiationAwareBeanPostProcessor) {
  58. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
  59. PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
  60. if (pvsToUse == null) {
  61. if (filteredPds == null) {
  62. filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
  63. }
  64. //对所有需要依赖检查的属性进行后处理
  65. //四、处理属性值(@Autowired、@Value)
  66. pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
  67. if (pvsToUse == null) {
  68. return;
  69. }
  70. }
  71. pvs = pvsToUse;
  72. }
  73. }
  74. }
  75. // 检查是否满足相关依赖关系,对应的depends-on属性,3.0后已弃用
  76. if (needsDepCheck) {
  77. if (filteredPds == null) {
  78. filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
  79. }
  80. checkDependencies(beanName, mbd, filteredPds, pvs);
  81. }
  82. // 五、填充属性
  83. if (pvs != null) {
  84. applyPropertyValues(beanName, mbd, bw, pvs);
  85. }
  86. }

一、postProcessAfterInstantiation:修改Bean实例

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

  1. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  2. for (BeanPostProcessor bp : getBeanPostProcessors()) {
  3. if (bp instanceof InstantiationAwareBeanPostProcessor) {
  4. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
  5. if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
  6. return;
  7. }
  8. }
  9. }
  10. }

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

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

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

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

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

CommonAnnotationBeanPostProcessor:处理@Resource

AutowiredAnnotationBeanPostProcessor:处理@Autowired、@Value。

详情:https://www.jb51.net/article/277330.htm

五、applyPropertyValues:填充属性

  1. protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
  2. if (pvs.isEmpty()) {
  3. return;
  4. }
  5. if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
  6. ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
  7. }
  8. MutablePropertyValues mpvs = null;
  9. List<PropertyValue> original;
  10. if (pvs instanceof MutablePropertyValues) {
  11. mpvs = (MutablePropertyValues) pvs;
  12. //如果mpvs中的值已经被转换为对应的类型那么可以直接设置到beanWrapper
  13. if (mpvs.isConverted()) {
  14. // Shortcut: use the pre-converted values as-is.
  15. try {
  16. bw.setPropertyValues(mpvs);
  17. return;
  18. } catch (BeansException ex) {
  19. throw new BeanCreationException(
  20. mbd.getResourceDescription(), beanName, "Error setting property values", ex);
  21. }
  22. }
  23. original = mpvs.getPropertyValueList();
  24. } else {
  25. //如果pvs并不是使用MutablePropertyValues封装的类型,那么直接使用原始的属性获取方法
  26. original = Arrays.asList(pvs.getPropertyValues());
  27. }
  28. TypeConverter converter = getCustomTypeConverter();
  29. if (converter == null) {
  30. converter = bw;
  31. }
  32. //获取对应的解析器
  33. BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
  34. // Create a deep copy, resolving any references for values.
  35. List<PropertyValue> deepCopy = new ArrayList<>(original.size());
  36. boolean resolveNecessary = false;
  37. //遍历属性,将属性转换为对应属性的类型
  38. for (PropertyValue pv : original) {
  39. if (pv.isConverted()) {
  40. deepCopy.add(pv);
  41. } else {
  42. String propertyName = pv.getName();
  43. Object originalValue = pv.getValue();
  44. if (originalValue == AutowiredPropertyMarker.INSTANCE) {
  45. Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
  46. if (writeMethod == null) {
  47. throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
  48. }
  49. originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
  50. }
  51. //解析、注入值
  52. Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
  53. Object convertedValue = resolvedValue;
  54. boolean convertible = bw.isWritableProperty(propertyName) &&
  55. !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
  56. if (convertible) {
  57. convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
  58. }
  59. // Possibly store converted value in merged bean definition,
  60. // in order to avoid re-conversion for every created bean instance.
  61. if (resolvedValue == originalValue) {
  62. if (convertible) {
  63. pv.setConvertedValue(convertedValue);
  64. }
  65. deepCopy.add(pv);
  66. } else if (convertible && originalValue instanceof TypedStringValue &&
  67. !((TypedStringValue) originalValue).isDynamic() &&
  68. !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
  69. pv.setConvertedValue(convertedValue);
  70. deepCopy.add(pv);
  71. } else {
  72. resolveNecessary = true;
  73. deepCopy.add(new PropertyValue(pv, convertedValue));
  74. }
  75. }
  76. }
  77. if (mpvs != null && !resolveNecessary) {
  78. mpvs.setConverted();
  79. }
  80. // Set our (possibly massaged) deep copy.
  81. try {
  82. bw.setPropertyValues(new MutablePropertyValues(deepCopy));
  83. } catch (BeansException ex) {
  84. throw new BeanCreationException(
  85. mbd.getResourceDescription(), beanName, "Error setting property values", ex);
  86. }
  87. }

解析、注入值

  1. public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
  2. // We must check each value to see whether it requires a runtime reference
  3. // to another bean to be resolved.
  4. // 5.1 解析引用
  5. if (value instanceof RuntimeBeanReference) {
  6. RuntimeBeanReference ref = (RuntimeBeanReference) value;
  7. return resolveReference(argName, ref);
  8. }
  9. // 如果根据另一个Bean的name进行依赖,进入下面的分支
  10. else if (value instanceof RuntimeBeanNameReference) {
  11. String refName = ((RuntimeBeanNameReference) value).getBeanName();
  12. refName = String.valueOf(doEvaluate(refName));
  13. if (!this.beanFactory.containsBean(refName)) {
  14. throw new BeanDefinitionStoreException(
  15. "Invalid bean name '" + refName + "' in bean reference for " + argName);
  16. }
  17. return refName;
  18. }
  19. // 解析BeanDefinitionHolder
  20. else if (value instanceof BeanDefinitionHolder) {
  21. // Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
  22. BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
  23. return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
  24. }
  25. // 解析纯BeanDefinition
  26. else if (value instanceof BeanDefinition) {
  27. // Resolve plain BeanDefinition, without contained name: use dummy name.
  28. BeanDefinition bd = (BeanDefinition) value;
  29. String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
  30. ObjectUtils.getIdentityHexString(bd);
  31. return resolveInnerBean(argName, innerBeanName, bd);
  32. }
  33. // 解析数组
  34. else if (value instanceof ManagedArray) {
  35. // May need to resolve contained runtime references.
  36. ManagedArray array = (ManagedArray) value;
  37. Class<?> elementType = array.resolvedElementType;
  38. if (elementType == null) {
  39. String elementTypeName = array.getElementTypeName();
  40. if (StringUtils.hasText(elementTypeName)) {
  41. try {
  42. elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
  43. array.resolvedElementType = elementType;
  44. }
  45. catch (Throwable ex) {
  46. // Improve the message by showing the context.
  47. throw new BeanCreationException(
  48. this.beanDefinition.getResourceDescription(), this.beanName,
  49. "Error resolving array type for " + argName, ex);
  50. }
  51. }
  52. else {
  53. elementType = Object.class;
  54. }
  55. }
  56. return resolveManagedArray(argName, (List<?>) value, elementType);
  57. }
  58. //5.2解析List
  59. else if (value instanceof ManagedList) {
  60. // May need to resolve contained runtime references.
  61. return resolveManagedList(argName, (List<?>) value);
  62. }
  63. // 解析Set
  64. else if (value instanceof ManagedSet) {
  65. // May need to resolve contained runtime references.
  66. return resolveManagedSet(argName, (Set<?>) value);
  67. }
  68. // 解析Map
  69. else if (value instanceof ManagedMap) {
  70. // May need to resolve contained runtime references.
  71. return resolveManagedMap(argName, (Map<?, ?>) value);
  72. }
  73. // 解析Properties
  74. else if (value instanceof ManagedProperties) {
  75. Properties original = (Properties) value;
  76. Properties copy = new Properties();
  77. original.forEach((propKey, propValue) -> {
  78. if (propKey instanceof TypedStringValue) {
  79. propKey = evaluate((TypedStringValue) propKey);
  80. }
  81. if (propValue instanceof TypedStringValue) {
  82. propValue = evaluate((TypedStringValue) propValue);
  83. }
  84. if (propKey == null || propValue == null) {
  85. throw new BeanCreationException(
  86. this.beanDefinition.getResourceDescription(), this.beanName,
  87. "Error converting Properties key/value pair for " + argName + ": resolved to null");
  88. }
  89. copy.put(propKey, propValue);
  90. });
  91. return copy;
  92. }
  93. // 解析String
  94. else if (value instanceof TypedStringValue) {
  95. // Convert value to target type here.
  96. TypedStringValue typedStringValue = (TypedStringValue) value;
  97. Object valueObject = evaluate(typedStringValue);
  98. try {
  99. Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
  100. if (resolvedTargetType != null) {
  101. return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
  102. }
  103. else {
  104. return valueObject;
  105. }
  106. }
  107. catch (Throwable ex) {
  108. // Improve the message by showing the context.
  109. throw new BeanCreationException(
  110. this.beanDefinition.getResourceDescription(), this.beanName,
  111. "Error converting typed String value for " + argName, ex);
  112. }
  113. }
  114. else if (value instanceof NullBean) {
  115. return null;
  116. }
  117. else {
  118. return evaluate(value);
  119. }
  120. }

5.1 解析依赖

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

  1. private Object resolveReference(Object argName, RuntimeBeanReference ref) {
  2. try {
  3. Object bean;
  4. // 获取BeanName
  5. String refName = ref.getBeanName();
  6. refName = String.valueOf(doEvaluate(refName));
  7. // 如果Bean在父容器,则去父容器取
  8. if (ref.isToParent()) {
  9. if (this.beanFactory.getParentBeanFactory() == null) {
  10. throw new BeanCreationException(
  11. this.beanDefinition.getResourceDescription(), this.beanName,
  12. "Can't resolve reference to bean '" + refName +
  13. "' in parent factory: no parent factory available");
  14. }
  15. bean = this.beanFactory.getParentBeanFactory().getBean(refName);
  16. }
  17. else {
  18. // 在本容器,调用getBean
  19. bean = this.beanFactory.getBean(refName);
  20. this.beanFactory.registerDependentBean(refName, this.beanName);
  21. }
  22. if (bean instanceof NullBean) {
  23. bean = null;
  24. }
  25. return bean;
  26. }
  27. catch (BeansException ex) {
  28. throw new BeanCreationException(
  29. this.beanDefinition.getResourceDescription(), this.beanName,
  30. "Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
  31. }
  32. }

5.2 解析List

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

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

以上就是Spring populateBean属性赋值和自动注入的详细内容,更多关于Spring populateBean属性的资料请关注w3xue其它相关文章!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号