SpringBoot深入理解 -- @AliasFor注解的作用
SpringBoot源码解析 -- SpringBoot启动过程
SpringBoot源码解析 -- AutoConfigure的实现原理
SpringBoot源码解析 -- @ComponentScan的实现原理
SpringBoot源码解析 -- @Value,@Autowired实现原理
SpringBoot源码解析 -- Tomcat,SpringMVC启动
SpringBoot源码解析 -- Logging,Environment启动
前面解析@ComponentScan实现原理的文章说了,Spring如何扫描@Component注解的Bean,但扫描的Bean如何注入属性呢?
我们都知道该功能主要使用@Value,@Autowired注解完成,这篇文章主要解析Spring中@Value,@Autowired实现原理。
源码分析基于spring boot 2.1
前面解析Spring注入属性过程的文章中,说过AbstractAutowireCapableBeanFactory#populateBean方法负责注入bean的属性,其实@Value,@Autowired等注解也是在该方法处理。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
...
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// #1
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
...
}
#1
调用InstantiationAwareBeanPostProcessor#postProcessProperties扩展方法,这里处理@Value,@Autowired等注解。
在解析SpringBoot启动过程的文章中,说过了AutowiredAnnotationBeanPostProcessor负责处理@Value,@Autowired等注解。
(AutowiredAnnotationBeanPostProcessor是InstantiationAwareBeanPostProcessor的实现类)
AutowiredAnnotationBeanPostProcessor#postProcessProperties
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// #1
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// #2
metadata.inject(bean, beanName, pvs);
}
...
return pvs;
}
#1
获取Class中关于属性注入相关注解的元数据
#2
完成属性注入操作
AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata -> buildAutowiringMetadata
private InjectionMetadata buildAutowiringMetadata(final Class> clazz) {
LinkedList elements = new LinkedList();
Class> targetClass = clazz;
do {
final LinkedList currElements =
new LinkedList();
ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() {
@Override
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
// #1
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
}
});
... // #2
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
}
#1
查找field是否有@Autowired,@Value等注解
#2
查找method是否有@Autowired,@Value等注解
InjectionMetadata#inject方法遍历所有的InjectedElement,调用AutowiredMethodElement,AutowiredFieldElement的inject方法,这里只关注AutowiredFieldElement#inject
InjectionMetadata#inject -> AutowiredFieldElement#inject
protected void inject(Object bean, String beanName, 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);
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// #1
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
...
}
if (value != null) {
// #2
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
#1
根据注解元数据,解析属性值
#2
将解析的结果值注入到bean
DefaultListableBeanFactory#resolveDependency -> DefaultListableBeanFactory#doResolveDependency
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
Set autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class> type = descriptor.getDependencyType();
// #1
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
// #2
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
//#3
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
// #4
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// #5
Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// #6
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(type, matchingBeans);
}
else {
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
Map.Entry entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
return (instanceCandidate instanceof Class ?
descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
#1
如果存在@Value注解,获取注解的value值
#2
解析@Value注解的值,如果这里使用占位符引用了配置文件,默认使用PropertyPlaceholderConfigurer#PlaceholderResolvingStringValueResolver解析配置文件中的值。
PropertyPlaceholderConfigurer是一个常用的BeanFactoryPostProcessor,它可以在Spring启动时,将Bean属性配置的占位符解析为配置属性的值
#3
默认使用SimpleTypeConverter将配置值转化为属性要求的类型(例如属性为int类型,则需要将String转换为int类型)
这里最终也会复用TypeConverterDelegate#convertIfNecessary方法。
#4
解析数组、list、map等类型的依赖,使用对应的TypeConverter处理
#5
处理@Autowire,找到候选的bean
#6
存在多个候选的bean,spring要按优先级决定用哪个,较复杂,不深入。
DefaultListableBeanFactory#findAutowireCandidates
protected Map findAutowireCandidates(
String beanName, Class> requiredType, DependencyDescriptor descriptor) {
// #1
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map result = new LinkedHashMap(candidateNames.length);
// #2
for (Class> autowiringType : this.resolvableDependencies.keySet()) {
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = this.resolvableDependencies.get(autowiringType);
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
//#3
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
...
return result;
}
#1
按类型查找spring上下文中所有的bean
#2
从当前已存在的依赖关系中查找
#3
遍历#1
步骤中找到的bean,如果满足Autowire要求,添加到结果
这里检查候选类的类型是否匹配,是否满足@Qualifier的要求,不继续深入,有兴趣的同学自行阅读源码。
如果您觉得本文不错,欢迎关注我的微信公众号,您的关注是我坚持的动力!