@Autowire源码分析,@Autowire是怎么实现依赖注入的

65 阅读4分钟

文章目录

写在前面

我们经常用@Autowire,那@Autowire是怎么实现自动注入的呢?

一起分析源码看看吧!

关键类AutowiredAnnotationBeanPostProcessor

该场景只适用于基于注解方式启动的容器。

1、AutowiredAnnotationBeanPostProcessor的注册

先上一段代码:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

// 注册 Configuration Class
context.register(AutowiredBeanDemo.class);

// 启动 Spring 应用上下文
context.refresh();

// 关闭 Spring 应用上下文
context.close();

代码很简单,其中,@Autowire的处理关键类AutowiredAnnotationBeanPostProcessor的处理就隐藏在new AnnotationConfigApplicationContext()这个代码里,我们继续往下看:

// org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext()
public AnnotationConfigApplicationContext() {
	this.reader = new AnnotatedBeanDefinitionReader(this);
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}

上面源码中,会new一个AnnotatedBeanDefinitionReader,而Springboot启动web项目也会new这样一个类,它们的处理逻辑基本是相同的。

在AnnotatedBeanDefinitionReader构造器中,会进行以下的处理:

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
	this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
	Assert.notNull(environment, "Environment must not be null");
	this.registry = registry;
	this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
	// 注册AnnotationConfigProcessors
	AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

在源码最后,会调用工具类注册AnnotationConfigProcessors:

// org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry)
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
	registerAnnotationConfigProcessors(registry, null);
}

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
		BeanDefinitionRegistry registry, @Nullable Object source) {

	DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
	if (beanFactory != null) {
		if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
			beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
		}
		if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
			beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
		}
	}

	Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

	if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	// 注册AutowiredAnnotationBeanPostProcessor
	if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
	if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
	if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition();
		try {
			def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
					AnnotationConfigUtils.class.getClassLoader()));
		}
		catch (ClassNotFoundException ex) {
			throw new IllegalStateException(
					"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
		}
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
	}

	if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
	}

	return beanDefs;
}

上面源码我们可以分析出来,会依次注册ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor、EventListenerMethodProcessor、DefaultEventListenerFactory等,很多BeanPostProcessor顾名思义,就能知道大体是干什么的。

我们今天主要是研究AutowiredAnnotationBeanPostProcessor。
到此为止,AutowiredAnnotationBeanPostProcessor已经注册到BeanFactory中作为一个BeanDefinition了。

2、postProcessMergedBeanDefinition的处理逻辑

AutowiredAnnotationBeanPostProcessor实现了MergedBeanDefinitionPostProcessor,在重写的postProcessMergedBeanDefinition方法中,对Bean标注了@Autowired、@Value、@Inject的字段、方法进行了预处理,最终是在postProcessProperties中完成的自动注入。 在这里插入图片描述

3、AutowiredAnnotationBeanPostProcessor的处理过程

在Bean的生命周期 属性赋值前阶段,会调用InstantiationAwareBeanPostProcessor 的postProcessProperties方法,而AutowiredAnnotationBeanPostProcessor正式实现了InstantiationAwareBeanPostProcessor 接口,并实现了postProcessProperties方法。

关于Bean生命周期的属性赋值前阶段请移步:
Spring Bean生命周期——从源码角度详解Spring Bean的生命周期(下)

我们来分析一下AutowiredAnnotationBeanPostProcessor的postProcessProperties方法:

// org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
	InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
	try {
		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;
}

metadata.inject会调用InjectionMetadata的方法:

// org.springframework.beans.factory.annotation.InjectionMetadata#inject
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) {
			if (logger.isTraceEnabled()) {
				logger.trace("Processing injected element of bean '" + beanName + "': " + element);
			}
			element.inject(target, beanName, pvs);
		}
	}
}

InjectedElement有两种实现,对应一种是方法注入,一种是字段注入。

字段注入

// org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
@Override
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 {
			// 获取字段的属性值,如果是注入Bean会调用beanFactory的getBean
			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) {
		ReflectionUtils.makeAccessible(field);
		field.set(bean, value);
	}
}
}

我们发现,是通过BeanFactory来获取Bean,然后通过反射将字段的属性值设置上的。

方法注入

// org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement#inject
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
	if (checkPropertySkipping(pvs)) {
		return;
	}
	Method method = (Method) this.member;
	Object[] arguments;
	if (this.cached) {
		// Shortcut for avoiding synchronization...
		arguments = resolveCachedArguments(beanName);
	}
	else {
		int argumentCount = method.getParameterCount();
		arguments = new Object[argumentCount];
		DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
		Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount);
		Assert.state(beanFactory != null, "No BeanFactory available");
		TypeConverter typeConverter = beanFactory.getTypeConverter();
		for (int i = 0; i < arguments.length; i++) {
			MethodParameter methodParam = new MethodParameter(method, i);
			DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
			currDesc.setContainingClass(bean.getClass());
			descriptors[i] = currDesc;
			try {
				// 循环遍历方法参数,通过BeanFactory的getBean获取
				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);
					registerDependentBeans(beanName, autowiredBeans);
					if (autowiredBeans.size() == argumentCount) {
						Iterator<String> it = autowiredBeans.iterator();
						Class<?>[] paramTypes = method.getParameterTypes();
						for (int i = 0; i < paramTypes.length; i++) {
							String autowiredBeanName = it.next();
							if (beanFactory.containsBean(autowiredBeanName) &&
									beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
								cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
										descriptors[i], autowiredBeanName, paramTypes[i]);
							}
						}
					}
					this.cachedMethodArguments = cachedMethodArguments;
				}
				else {
					this.cachedMethodArguments = null;
				}
				this.cached = true;
			}
		}
	}
	if (arguments != null) {
		try {
			ReflectionUtils.makeAccessible(method);
			method.invoke(bean, arguments);
		}
		catch (InvocationTargetException ex) {
			throw ex.getTargetException();
		}
	}
}

我们发现,也是通过BeanFactory的getBean来获取要注入的Bean,通过反射将方法的参数注入到方法中。

4、属性赋值

无标题.png