乐趣区

关于springboot:Spring-Boot-Autowired-Resource-属性赋值时机

还是先贴出测试类:

@Service
public class TransactionServiceTest {
    @Resource
    private IQrcodeAdScheduleService qrcodeAdScheduleService;
}

Spring Boot 启动之后的的调用栈信息如下:
图 1
图 2
由图 1,图 2 可知 InjectionMetadata.inject() 执行属性织入逻辑,上面是局部细节

protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
                throws Throwable {if (this.isField) {Field field = (Field) this.member;
                ReflectionUtils.makeAccessible(field);
                // 通过反射对指标 target 对象也就是咱们之前定义的 TransactionServiceTest 的属性赋值
                field.set(target, getResourceToInject(target, requestingBeanName));
            }
}

其中,CommonAnnotationBeanPostProcessor.ResourceElement 的 member 属性存储的是 Filed 信息,对于本示例就是:
图 3
对于 @Autowired 来说,就是 AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement.inject():

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<String> autowiredBeanNames = new LinkedHashSet<>(1);
                Assert.state(beanFactory != null, "No BeanFactory available");
                TypeConverter typeConverter = beanFactory.getTypeConverter();
                try {// 递归调用 createBean() 实例化指标 bean 的属性 bean 实例
                    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) {
                // 通过 field 进行赋值
                ReflectionUtils.makeAccessible(field);
                field.set(bean, value);
            }
        }
}

其余的流程一毛一样啊~好了,总结的事件,交给读者敌人吧~(太困了,该劳动了)

退出移动版