含义:向属性注入JavaBea,默认按照类型通过set方法进行自动装配。
如果spring容器中没有可以与之匹配的类则会报错:NoSuchBeanDefinitionException。
如果spring容器有多个类型可以匹配,@Autowired注解会自动切换为按照名称(属性名)匹配,如果还没有则会报错:NoUniqueBeanDefinitionException。
在bean的生命周期中,贯穿着很多后置处理器,这些处理器为bean的生命周期各阶段提供拓展。属性赋值阶段是在bean实例化后立即执行。@Autowired注解的实现过程就是调用了AutowiredAnnotationBeanPostProcessor类中的方法。
核心方法postProcessProperties:
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//1.获取当前类中标注了@Autowired的成员变量和方法的参数封装在metadata对象里
InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//2.利用反射赋值
metadata.inject(bean, beanName, pvs);
return pvs;
} catch (BeanCreationException var6) {
throw var6;
} catch (Throwable var7) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);
}
}
1.调用findAutowiringMetadata方法查询
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
//获取当前bean的名称
String cacheKey = StringUtils.hasLength(beanName) ? beanName : clazz.getName();
//在缓存中查找是否有当前类的信息
InjectionMetadata metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized(this.injectionMetadataCache) {
metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
//调用此方法解析当前类,获得所有标注@AutoWired的字段 并存入metada中
metadata = this.buildAutowiringMetadata(clazz);
//存入缓存中
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
//返回得到@AutoWired的字段的metadata
return metadata;
}
2.执行inject方法完成属性注入
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//metadata中的数据放在集合中
Collection<InjectionMetadata.InjectedElement> checkedElements = this.checkedElements;
Collection<Injectio
nMetadata.InjectedElement> elementsToIterate = checkedElements != null ? checkedElements : this.injectedElements;
if (!((Collection)elementsToIterate).isEmpty()) {
Iterator var6 = ((Collection)elementsToIterate).iterator();
//遍历集合拿到标注了@AutoWired的成员变量和方法
while(var6.hasNext()) {
InjectionMetadata.InjectedElement element = (InjectionMetadata.InjectedElement)var6.next();
//遍历调用内部类的方法完成属性赋值
element.inject(target, beanName, pvs);
}
}
}
内部类的inject方法
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs) throws Throwable {
//判断是方法还是成员变量
if (this.isField) {
//得到bean的Field对象
Field field = (Field)this.member;
//底层做了判断然后停止修饰符检查
ReflectionUtils.makeAccessible(field);
//利用反射给成员变量赋值
field.set(target, this.getResourceToInject(target, requestingBeanName));
} else {
if (this.checkPropertySkipping(pvs)) {
return;
}
try {
//得到bean的方法对象
Method method = (Method)this.member;
//停止修饰符检查
ReflectionUtils.makeAccessible(method);
//利用invoke给targe赋值,值为此方法的返回值
method.invoke(target, this.getResourceToInject(target, requestingBeanName));
} catch (InvocationTargetException var5) {
throw var5.getTargetException();
}
}
}
此处的getResourceToInject方法返回为null,调用的应该是其他子类的重写方法
查看类的结构发现有重写的:此方法判断加载类型:
第一种是用懒加载:使用代理模式,先返回代理对象。等需要时在调用getResource方法获得被代理的对象。
第二种就是直接赋值:底层会调用本类中的autowireResource方法,在BeanFactory中根据名称查找是所需bean的对象。完成属性赋值。
protected Object autowireResource(BeanFactory factory, CommonAnnotationBeanPostProcessor.LookupElement element, @Nullable String requestingBeanName) throws NoSuchBeanDefinitionException {
String name = element.name;
Object resource;
Object autowiredBeanNames;
if (factory instanceof AutowireCapableBeanFactory) {
AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory)factory;
DependencyDescriptor descriptor = element.getDependencyDescriptor();
if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
autowiredBeanNames = new LinkedHashSet();
resource = beanFactory.resolveDependency(descriptor, requestingBeanName, (Set)autowiredBeanNames, (TypeConverter)null);
if (resource == null) {
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
}
} else {
resource = beanFactory.resolveBeanByName(name, descriptor);
autowiredBeanNames = Collections.singleton(name);
}
} else {
resource = factory.getBean(name, element.lookupType);
autowiredBeanNames = Collections.singleton(name);
}
if (factory instanceof ConfigurableBeanFactory) {
ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory)factory;
Iterator var11 = ((Set)autowiredBeanNames).iterator();
while(var11.hasNext()) {
String autowiredBeanName = (String)var11.next();
if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) {
beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);
}
}
}
return resource;
}
这里面底层调用了很多方法,做了大量的判断。我也只是一个新手,尽量写出自己的理解,有很多地方也很模糊,也借阅了其他大佬的解读。
此地址为参考文章。