@Autowired依赖注入
- 本文源码基于spring-framework-5.3.10。
- 源码位置:org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(PropertyValues, Object, String)
- 他在Bean的生命周期的实例化后之后,初始化前(或者说各种Aware回调之前)之前调用。
@Autowired依赖注入的大致流程
- 寻找注入点:被@Autowired注解的方法和字段
- 遍历每个注入点
- 根据注入点类型去寻找bean:属性的类型、方法参数的类型
- 找到一个Bean进行注入。没有找到Bean,如果是必填的,抛异常。找到多个Bean,去取出唯一的Bean
- 判断是不是isAutowireCandidate
- 判断是不是数组、Map、列表..
- 这时候如果还有多个:取@Primary标注了的Bean
- 这时候如果还有多个:取优先级最高的Bean
- 这时候如果还有多个:根据名字(属性就是属性的名字,方法是参数的名字)筛选出唯一一个
@Autowired依赖注入源码分析
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 寻找注入点(所有被@Autowired注解了的Field或Method)
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 依赖注入。Field与Method的实现方式不同
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
// 返回全部的属性值对象
return pvs;
}
/**
* 依赖注入:这个方法主要作用是循环每个注入点进行注入。区分字段和方法进行注入
*/
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// 得到全部的注入点
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
// 遍历每个注入点进行依赖注入
for (InjectedElement element : elementsToIterate) {
element.inject(target, beanName, pvs);
}
}
}
@Autowired针对字段的注入方式
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// 得到当前注入点的字段
Field field = (Field) this.member;
// 定义一个具体注入的值
Object value;
if (this.cached) {
// 对于原型Bean,第一次创建的时候,也找注入点,然后进行注入,此时cached为false,注入完了之后cached为true
// 第二次创建的时候,先找注入点(此时会拿到缓存好的注入点),也就是AutowiredFieldElement对象,此时cache为true,也就进到此处了
// 注入点内并没有缓存被注入的具体Bean对象,而是beanName,这样就能保证注入到不同的原型Bean对象
try {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
else {
// 根据filed从BeanFactory中获取的匹配的Bean对象
value = resolveFieldValue(field, bean, beanName);
}
// 反射给filed赋值
if (value != null) {
// 主要设置私有私有可以访问,标记在反射的时候跳过校验!
ReflectionUtils.makeAccessible(field);
// 给字段设置值!
field.set(bean, value);
}
}
/**
* 根据filed从BeanFactory中获取的匹配的Bean对象
*/
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
// 根据当前字段以及@autowired(required = true)构建一个属性描述器
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
// 设置属性描述器对应的class为当前Bean的class
desc.setContainingClass(bean.getClass());
// 得到需要注入的BeanName几个
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
// 得到当前Bean工厂的类型转化器
TypeConverter typeConverter = beanFactory.getTypeConverter();
// 属性实际注入的值
Object value;
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) {
// 缓存的属性描述器
Object cachedFieldValue = null;
// 要注入的值不为null或者这个属性是必填的!
if (value != null || this.required) {
// 属性描述器赋值
cachedFieldValue = desc;
// 注册一下beanName依赖了autowiredBeanNames,
registerDependentBeans(beanName, autowiredBeanNames);
// 只有一个,找到了唯一的Bean。上面的定义,这里肯定是一个
if (autowiredBeanNames.size() == 1) {
// 得到要注入的BeanName
String autowiredBeanName = autowiredBeanNames.iterator().next();
// Bean工厂中可以获取当前Bean,并且类型与要注入的类型一致
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
// 构造一个ShortcutDependencyDescriptor作为缓存,保存了当前filed所匹配的autowiredBeanName,而不是对应的bean对象(考虑原型bean)
cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
// 全局缓存的属性描述器赋值
this.cachedFieldValue = cachedFieldValue;
// 下次缓存判断就不会进来了
this.cached = true;
}
}
// 返回具体注入的值
return value;
}
@Autowired针对方法的注入方式
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// 如果pvs中已经有当前注入点的值了,则跳过注入。程序员自己设置了值
if (checkPropertySkipping(pvs)) {
return;
}
// 得到当前要注入的的方法
Method method = (Method) this.member;
// 得到当前方法的参数
Object[] arguments;
if (this.cached) {
try {
// 使用缓存的方式进行注入
arguments = resolveCachedArguments(beanName);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
arguments = resolveMethodArguments(method, bean, beanName);
}
}
else {
// 根据method从BeanFactory中获取的参数匹配的Bean对象
arguments = resolveMethodArguments(method, bean, beanName);
}
// 参数不为空的时候(没有抛异常的时候),进行方法调用
if (arguments != null) {
try {
// 主要设置私有方法可以访问,标记在反射的时候跳过校验!
ReflectionUtils.makeAccessible(method);
// 执行具体的方法
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
/**
* 根据method从BeanFactory中获取的参数匹配的Bean对象
*/
private Object[] resolveMethodArguments(Method method, Object bean, @Nullable String beanName) {
// 得到方法参数的个数
int argumentCount = method.getParameterCount();
// 定义一个参数的数组
Object[] arguments = new Object[argumentCount];
// 定义一个依赖描述器
DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
// 定义要注入的每个Bean的集合
Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount);
Assert.state(beanFactory != null, "No BeanFactory available");
// 得到当前Bean工厂的类型转化器
TypeConverter typeConverter = beanFactory.getTypeConverter();
// 遍历每个方法参数,找到匹配的bean对象
for (int i = 0; i < arguments.length; i++) {
// 构建具体的参数对象
MethodParameter methodParam = new MethodParameter(method, i);
// 构建具体的依赖描述器对象
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
// 设置属性描述器对应的class为当前Bean的class
currDesc.setContainingClass(bean.getClass());
// 依赖描述器集合数据设置
descriptors[i] = currDesc;
try {
// 获取要注入的值
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
// 有任意一个参数没找到,并且当前的方法不是必须的要注入的。直接放弃继续找参数
if (arg == null && !this.required) {
arguments = null;
break;
}
// 参数赋值
arguments[i] = arg;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
synchronized (this) {
// 缓存不存在的时候(走过一遍的时候会有缓存),会走下面的逻辑
if (!this.cached) {
// 存在参数(得到了参数值)
if (arguments != null) {
// 得到参数值的数组
DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
// 注册一下beanName依赖了autowiredBeanNames。
registerDependentBeans(beanName, autowiredBeans);
// 得到的参数和需要的参数数量相同的时候
if (autowiredBeans.size() == argumentCount) {
// 得到要注入参数的迭代器
Iterator<String> it = autowiredBeans.iterator();
// 得到当前方法各个参数的类型
Class<?>[] paramTypes = method.getParameterTypes();
// 遍历每一个参数的类型
for (int i = 0; i < paramTypes.length; i++) {
// 得到类型对应的Bean名称
String autowiredBeanName = it.next();
// 能在Bean工厂找到当前参数的Bean,并且类型能匹配上,参数值赋值
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
descriptors[i], autowiredBeanName, paramTypes[i]);
}
}
}
// 设置全局的参数对应的BeanName
this.cachedMethodArguments = cachedMethodArguments;
}
else {
// 参数值不全的时候,或者没有参数的时候,这里设置为null
this.cachedMethodArguments = null;
}
// 下次缓存判断就不会进来了
this.cached = true;
}
}
// 返回具体注入需要的参数值的集合
return arguments;
}
获取要注入的值外部方法:resolveDependency源码分析
/**
* DependencyDescriptor descriptor:依赖描述器,可能是字段,方法
* requestingBeanName:请求的BeanName
* autowiredBeanNames:需要注入的BeanName集合
* typeConverter:类型转换器
*/
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
// 用来获取方法入参名字的
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
// 所需要的类型是Optional,包装成Optional对象,核心调用的也是doResolveDependency
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
// 所需要的的类型是ObjectFactory,或ObjectProvider
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 {
// 在属性或set方法上使用了@Lazy注解,那么则构造一个代理对象并返回,真正使用该代理对象时才进行类型筛选Bean
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
// 没有@Lazy注解的时候
if (result == null) {
// descriptor表示某个属性或某个set方法
// requestingBeanName表示正在进行依赖注入的Bean
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
获取要注入的值内部方法:doResolveDependency源码分析
/**
* 最核心的方法,如何寻找Bean
* descriptor:表示某个属性或某个set方法
* beanName:表示正在进行依赖注入的Bean
* autowiredBeanNames:需要注入的BeanName列表
* typeConverter:类型转换器
*/
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
// 设置当前的descriptor(存储了方法字段参数等信息)为当前注入点
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 如果当前descriptor之前做过依赖注入了,则可以直接取shortcut了,相当于缓存
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
// 找到要注入的类型,可能是字段的类型,也可能是方法参数的类型
Class<?> type = descriptor.getDependencyType();
// 获取@Value所指定的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
// 字段上或者方法参数存在@Value注解
if (value != null) {
// 占位符或者spring表达式的解析
if (value instanceof String) {
// 占位符填充(${})
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
// 解析Spring表达式(#{})
value = evaluateBeanDefinitionString(strVal, bd);
}
// 将value转化为descriptor所对应的类型
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...
// 不是string转Bean,变为使用自定义的转化器
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
// 如果descriptor所对应的类型是数组、Map这些,就将descriptor对应的类型所匹配的所有bean方法,不用进一步做筛选了
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 找到所有Bean,key是beanName, value有可能是bean对象,有可能是beanClass(接口的方式注入,优先级较低,类没有加载)
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
// required为true,抛异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
// 定义要注入的Bean名称
String autowiredBeanName;
// 定义要注入的Bean值
Object instanceCandidate;
if (matchingBeans.size() > 1) {
// 根据类型找到了多个Bean,进一步筛选出某一个, @Primary-->优先级最高--->name
// 这里实现的是ByName
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
// 注入的Bean的名称为null
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).
// 非必填返回null
return null;
}
}
// 给当前要注入的具体指赋值
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
// 只找到了一个Bean
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
// 给当前要注入的BeanName赋值
autowiredBeanName = entry.getKey();
// 给当前要注入的具体指赋值
instanceCandidate = entry.getValue();
}
// 记录匹配过的beanName
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
// 有可能筛选出来的是某个bean的类型,此处就进行实例化,调用getBean
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);
}
}
针对数组、Map的特殊处理:resolveMultipleBeans源码分析
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
// 得到当前要注入的类型
Class<?> type = descriptor.getDependencyType();
// 属于Stream相关的
if (descriptor instanceof StreamDependencyDescriptor) {
// 找到type所匹配的所有bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
// 构造成一个stream
Stream<Object> 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;
}
// 属于数组相关的
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;
}
// 根据数组元素类型找到所匹配的所有Bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
new MultiElementDescriptor(descriptor));
// 没有获取到bean,返回Null
if (matchingBeans.isEmpty()) {
return null;
}
// 把需要注入的BeanName传入的数组中
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
// 进行类型转化
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
// Map的Values转为数组
Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);
// 排序
if (result instanceof Object[]) {
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
if (comparator != null) {
Arrays.sort((Object[]) result, comparator);
}
}
return result;
}
// Collection处理
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
// 找到这个列表的具体类型
Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
// 类似是null,直接返回
if (elementType == null) {
return null;
}
// 找到type所匹配的所有bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
new MultiElementDescriptor(descriptor));
// 没有找到Bean,直接返回
if (matchingBeans.isEmpty()) {
return null;
}
// 把需要注入的BeanName传入的数组中
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
// 类型转换
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
// 把Map的Values拿出来
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
// 遍历拿到的Values
if (result instanceof List) {
// 排序
if (((List<?>) result).size() > 1) {
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
if (comparator != null) {
((List<?>) result).sort(comparator);
}
}
}
// 返回链表的结果
return result;
}
// Map类型处理
else if (Map.class == type) {
// 找到Map的Key的类型
ResolvableType mapType = descriptor.getResolvableType().asMap();
Class<?> keyType = mapType.resolveGeneric(0);
// 如果Map的key不是String
if (String.class != keyType) {
return null;
}
Class<?> valueType = mapType.resolveGeneric(1);
// Map的Balue不能是null
if (valueType == null) {
return null;
}
// 找到type所匹配的所有bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
new MultiElementDescriptor(descriptor));
// 找到的Bean为空,直接返回null
if (matchingBeans.isEmpty()) {
return null;
}
// 把需要注入的BeanName传入的数组中
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
// 返回找到的所有Bean
return matchingBeans;
}
else {
// 不是上面的几种类型,直接返回null
return null;
}
}
@Autowire自己的ByName源码分析
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
// candidates表示根据类型所找到的多个Bean,判断这些Bean中是否有一个是@Primary的,存在多个@Primary注解,抛异常!
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
// 取优先级最高的Bean。这里的优先级指的是@Priority注解配置的优先级,数字越小,优先级越高!
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
// 匹配descriptor的名字,要么是字段的名字,要么是set方法入参的名字
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
// resolvableDependencies记录了某个类型对应某个Bean,启动Spring时会进行设置,比如BeanFactory.class对应BeanFactory实例
// 注意:如果是Spring自己的byType,descriptor.getDependencyName()将返回空,只有是@Autowired才会方法属性名或方法参数名
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}
获取方法入参名称:DefaultParameterNameDiscoverer源码分析
public DefaultParameterNameDiscoverer() {
// TODO Remove this conditional inclusion when upgrading to Kotlin 1.5, see https://youtrack.jetbrains.com/issue/KT-44594
if (KotlinDetector.isKotlinReflectPresent() && !NativeDetector.inNativeImage()) {
addDiscoverer(new KotlinReflectionParameterNameDiscoverer());
}
// 反射(1.8+):getParameterNames
addDiscoverer(new StandardReflectionParameterNameDiscoverer());
// ASM分析.class文件
addDiscoverer(new LocalVariableTableParameterNameDiscoverer());
}
结束语
- 获取更多本文的前置知识文章,以及新的有价值的文章,让我们一起成为架构师!
- 关注公众号,可以让你对MySQL、并发编程、spring源码有深入的了解!
- 关注公众号,后续持续高效的学习JVM!
- 这个公众号,无广告!!!每日更新!!!