依赖注入的实现由后置处理器AutowiredAnnotationBeanPostProcessor实现
类图
实现了InstantiationAwareBeanPostProcessor ,MergedBeanDefinitionPostProcessor接口,如果对这两个接口不熟悉的可以阅读上篇文章后置处理器,实现这两个接口就可以介入到Bean的实例化前后和bean的元数据信息解析
依赖注入过程:
第一步、解析注解信息
入口方法:
postProcessMergedBeanDefinition该方法的作用其实比较简单,就是为了缓存下后续需要用到数据,findAutowiringMetadata 这个方法是有缓存的
处理的,所以重复调用的话是直接从缓存获取数据,加快注入的效率。这个方法其实就是去查找被 Autowired、Value 注解的所有属性和方法,当然包
括了目标类的所有父类都会去查找,所以查找的过程其实是个递归的过程。找到所有的成员后,会创建即实例化
InjectionMetadata 对象并缓存到injectionMetadataCache 。
核心代码:
/**
*解析注解并缓存起来
**/
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
//解析所有@Autowired @Value注解的方法和变量
metadata = buildAutowiringMetadata(clazz);
//缓存起来
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
//解析带Autowired和@Value的字段
ReflectionUtils.doWithLocalFields(targetClass, field -> {
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}