文章目录

  • 前言
  • 1. @Value 的源码处理流程
  • 2. 源码分析
  • 2.1 后置处理器 AutowiredAnnotationBeanPostProcessor 的注册
  • 2.2 属性处理器 PropertySourcesPropertyResolver 的注册
  • 2.3 @Value 标注字段的依赖处理


前言

SpringBoot 提供了很多开箱即用的实用工具,比如我们可以使用 @Value 注解获取容器中的配置数据,自动完成属性的赋值,本文即从源码角度来解析 @Value 的实现机制

1. @Value 的源码处理流程

@Value 实现属性注入的源码流程如下图所示,笔者将其从组件的准备组件的使用分为了三个部分:

  1. @Value 后置处理器 AutowiredAnnotationBeanPostProcessor 的注册,这个后置处理器主要用于识别获取 @Value 中配置的属性字符串
  2. @Value 属性值来源处理器 PropertySourcesPropertyResolver 的注册,该处理器负责从容器中取得指定的属性值
  3. 创建 Bean 对象时,容器使用以上两个组件对 @Value 标注的属性进行依赖注入

springboot 幂等注解 实现 el表达式 springboot value注解原理_java

2. 源码分析

2.1 后置处理器 AutowiredAnnotationBeanPostProcessor 的注册

  1. SpringBoot 注解 @Import 的原理-ConfigurationClassPostProcessor 源码解析 中,笔者分析了 SpringBoot 的基础注解 @Import 功能实现依赖的核心组件 ConfigurationClassPostProcessor 的注册,本文 @Value 依赖的组件 AutowiredAnnotationBeanPostProcessor 的注册流程与其基本一致,都是从 SpringApplication#prepareContext() 方法触发,一直调用到 AnnotationConfigUtils#registerAnnotationConfigProcessors() 方法

AnnotationConfigUtils#registerAnnotationConfigProcessors() 负责解析注册比较重要的后置处理器,本文主要关注以下几个步骤:

  1. 新建 ContextAnnotationAutowireCandidateResolver 处理器,并通过beanFactory.setAutowireCandidateResolver() 调用 DefaultListableBeanFactory#setAutowireCandidateResolver() 方法将其缓存到容器内,后续将使用它来获取 @Value 注解中配置的字符串
  2. AutowiredAnnotationBeanPostProcessor 包装为 BeanDefinition 并注册,这个 Bean 后置处理器将用于处理 Bean 的内部属性依赖
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));
 	}

 	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;
 }
  1. DefaultListableBeanFactory#setAutowireCandidateResolver() 方的处理很简单,可以看到就是一个赋值操作,将新建的 AutowireCandidateResolver 子类 ContextAnnotationAutowireCandidateResolver 对象保存在内部
public void setAutowireCandidateResolver(final AutowireCandidateResolver autowireCandidateResolver) {
 	Assert.notNull(autowireCandidateResolver, "AutowireCandidateResolver must not be null");
 	if (autowireCandidateResolver instanceof BeanFactoryAware) {
 		if (System.getSecurityManager() != null) {
 			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
 				((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(DefaultListableBeanFactory.this);
 				return null;
 			}, getAccessControlContext());
 		}
 		else {
 			((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
 		}
 	}
 	this.autowireCandidateResolver = autowireCandidateResolver;
 }

2.2 属性处理器 PropertySourcesPropertyResolver 的注册

  1. SpringBoot 自动配置原理源码分析 中笔者分析了自动配置的实现原理,则可以知道自动配置类PropertyPlaceholderAutoConfiguration 中的 @Bean 标注的方法将被触发,用于创建对应的配置类对象 PropertySourcesPlaceholderConfigurer
@Configuration(proxyBeanMethods = false)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
public class PropertyPlaceholderAutoConfiguration {

 @Bean
 @ConditionalOnMissingBean(search = SearchStrategy.CURRENT)
 public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
 	return new PropertySourcesPlaceholderConfigurer();
 }

}
  1. PropertySourcesPlaceholderConfigurer 实现了 BeanFactoryPostProcessor 接口,则当容器刷新时创建 Bean 工厂后会被用于对 Bean 工厂进行后置处理,触发 PropertySourcesPlaceholderConfigurer#postProcessBeanFactory() 方法,该方法比较重要的处理如下:
  1. 初始化属性来源列表 propertySources,可以看到此处会将 Environment 作为属性值来源
  2. 新建封装了属性来源列表 propertySourcesPropertySourcesPropertyResolver 对象,该对象主要负责从属性源中获取指定的属性值
  3. 调用 PropertySourcesPlaceholderConfigurer#processProperties() 方法将 PropertySourcesPropertyResolver 对象入参,进行下一步配置
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
 	if (this.propertySources == null) {
 		this.propertySources = new MutablePropertySources();
 		if (this.environment != null) {
 			this.propertySources.addLast(
 				new PropertySource<Environment>(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) {
 					@Override
 					@Nullable
 					public String getProperty(String key) {
 						return this.source.getProperty(key);
 					}
 				}
 			);
 		}
 		try {
 			PropertySource<?> localPropertySource =
 					new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergeProperties());
 			if (this.localOverride) {
 				this.propertySources.addFirst(localPropertySource);
 			}
 			else {
 				this.propertySources.addLast(localPropertySource);
 			}
 		}
 		catch (IOException ex) {
 			throw new BeanInitializationException("Could not load properties", ex);
 		}
 	}

 	processProperties(beanFactory, new PropertySourcesPropertyResolver(this.propertySources));
 	this.appliedPropertySources = this.propertySources;
 }
  1. PropertySourcesPlaceholderConfigurer#processProperties() 方法的重要处理如下:
  1. 通过 propertyResolver.setPlaceholderPrefix() 等方法调用,为 PropertySourcesPropertyResolver 对象设置属性解析的前后缀为 ${},分隔符为 :
  2. 使用 lambda 表达式 作为 StringValueResolver 的实现,随后调用父类 PlaceholderConfigurerSupport#doProcessProperties() 方法
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
 		final ConfigurablePropertyResolver propertyResolver) throws BeansException {

 	propertyResolver.setPlaceholderPrefix(this.placeholderPrefix);
 	propertyResolver.setPlaceholderSuffix(this.placeholderSuffix);
 	propertyResolver.setValueSeparator(this.valueSeparator);

 	StringValueResolver valueResolver = strVal -> {
 		String resolved = (this.ignoreUnresolvablePlaceholders ?
 				propertyResolver.resolvePlaceholders(strVal) :
 				propertyResolver.resolveRequiredPlaceholders(strVal));
 		if (this.trimValues) {
 			resolved = resolved.trim();
 		}
 		return (resolved.equals(this.nullValue) ? null : resolved);
 	};

 	doProcessProperties(beanFactoryToProcess, valueResolver);
 }
  1. PlaceholderConfigurerSupport#doProcessProperties() 方法中,本文主要关注beanFactoryToProcess.addEmbeddedValueResolver() 调用。这个处理实际调用到AbstractBeanFactory#addEmbeddedValueResolver() 方法,会将上一步骤构造的 lambda 表达式作为 StringValueResolver 的实例保存在 Bean 工厂内部
protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
 		StringValueResolver valueResolver) {

 	BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);

 	String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
 	for (String curName : beanNames) {
 		// Check that we're not parsing our own bean definition,
 		// to avoid failing on unresolvable placeholders in properties file locations.
 		if (!(curName.equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) {
 			BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(curName);
 			try {
 				visitor.visitBeanDefinition(bd);
 			}
 			catch (Exception ex) {
 				throw new BeanDefinitionStoreException(bd.getResourceDescription(), curName, ex.getMessage(), ex);
 			}
 		}
 	}

 	// New in Spring 2.5: resolve placeholders in alias target names and aliases as well.
 	beanFactoryToProcess.resolveAliases(valueResolver);

 	// New in Spring 3.0: resolve placeholders in embedded values such as annotation attributes.
 	beanFactoryToProcess.addEmbeddedValueResolver(valueResolver);
 }
  1. AbstractBeanFactory#addEmbeddedValueResolver() 方法的实现如下,可以看到只是个内部缓存动作,至此解析由 ${} 包裹的属性的属性处理器已经注册到容器内部
@Override
 public void addEmbeddedValueResolver(StringValueResolver valueResolver) {
 	Assert.notNull(valueResolver, "StringValueResolver must not be null");
 	this.embeddedValueResolvers.add(valueResolver);
 }

2.3 @Value 标注字段的依赖处理

  1. 容器刷新过程中会触发创建 Bean 对象,这个流程必然调用到 DefaultListableBeanFactory#createBean() 方法,而这个方法由其父类方法AbstractAutowireCapableBeanFactory#createBean() 实现,可以看到以下调用中最终将触发执行 AbstractAutowireCapableBeanFactory#doCreateBean() 方法
@Override
 @SuppressWarnings("unchecked")
 public <T> T createBean(Class<T> beanClass) throws BeansException {
 	// Use prototype bean definition, to avoid registering bean as dependent bean.
 	RootBeanDefinition bd = new RootBeanDefinition(beanClass);
 	bd.setScope(SCOPE_PROTOTYPE);
 	bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader());
 	return (T) createBean(beanClass.getName(), bd, null);
 }

 @Override
 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
 		throws BeanCreationException {

 	if (logger.isTraceEnabled()) {
 		logger.trace("Creating instance of bean '" + beanName + "'");
 	}
 	RootBeanDefinition mbdToUse = mbd;

 	// Make sure bean class is actually resolved at this point, and
 	// clone the bean definition in case of a dynamically resolved Class
 	// which cannot be stored in the shared merged bean definition.
 	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
 	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
 		mbdToUse = new RootBeanDefinition(mbd);
 		mbdToUse.setBeanClass(resolvedClass);
 	}

 	// Prepare method overrides.
 	try {
 		mbdToUse.prepareMethodOverrides();
 	}
 	catch (BeanDefinitionValidationException ex) {
 		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
 				beanName, "Validation of method overrides failed", ex);
 	}

 	try {
 		// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
 		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
 		if (bean != null) {
 			return bean;
 		}
 	}
 	catch (Throwable ex) {
 		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
 				"BeanPostProcessor before instantiation of bean failed", ex);
 	}

 	try {
 		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
 		if (logger.isTraceEnabled()) {
 			logger.trace("Finished creating instance of bean '" + beanName + "'");
 		}
 		return beanInstance;
 	}
 	catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
 		// A previously detected exception with proper bean creation context already,
 		// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
 		throw ex;
 	}
 	catch (Throwable ex) {
 		throw new BeanCreationException(
 				mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
 	}
 }
  1. AbstractAutowireCapableBeanFactory#doCreateBean() 方法比较长,核心为以下两步:
  1. 调用 AbstractAutowireCapableBeanFactory#createBeanInstance() 方法创建属性空白的 Bean 实例
  2. 调用 AbstractAutowireCapableBeanFactory#populateBean() 方法为 Bean 实例填充属性
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
 		throws BeanCreationException {

 	// Instantiate the bean.
 	BeanWrapper instanceWrapper = null;
 	if (mbd.isSingleton()) {
 		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
 	}
 	if (instanceWrapper == null) {
 		instanceWrapper = createBeanInstance(beanName, mbd, args);
 	}
 	final Object bean = instanceWrapper.getWrappedInstance();
 	Class<?> beanType = instanceWrapper.getWrappedClass();
 	if (beanType != NullBean.class) {
 		mbd.resolvedTargetType = beanType;
 	}

 	// Allow post-processors to modify the merged bean definition.
 	synchronized (mbd.postProcessingLock) {
 		if (!mbd.postProcessed) {
 			try {
 				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
 			}
 			catch (Throwable ex) {
 				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 						"Post-processing of merged bean definition failed", ex);
 			}
 			mbd.postProcessed = true;
 		}
 	}

 	// Eagerly cache singletons to be able to resolve circular references
 	// even when triggered by lifecycle interfaces like BeanFactoryAware.
 	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
 			isSingletonCurrentlyInCreation(beanName));
 	if (earlySingletonExposure) {
 		if (logger.isTraceEnabled()) {
 			logger.trace("Eagerly caching bean '" + beanName +
 					"' to allow for resolving potential circular references");
 		}
 		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
 	}

 	// Initialize the bean instance.
 	Object exposedObject = bean;
 	try {
 		populateBean(beanName, mbd, instanceWrapper);
 		exposedObject = initializeBean(beanName, exposedObject, mbd);
 	}
 	catch (Throwable ex) {
 		if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
 			throw (BeanCreationException) ex;
 		}
 		else {
 			throw new BeanCreationException(
 					mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
 		}
 	}

 	if (earlySingletonExposure) {
 		Object earlySingletonReference = getSingleton(beanName, false);
 		if (earlySingletonReference != null) {
 			if (exposedObject == bean) {
 				exposedObject = earlySingletonReference;
 			}
 			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
 				String[] dependentBeans = getDependentBeans(beanName);
 				Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
 				for (String dependentBean : dependentBeans) {
 					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
 						actualDependentBeans.add(dependentBean);
 					}
 				}
 				if (!actualDependentBeans.isEmpty()) {
 					throw new BeanCurrentlyInCreationException(beanName,
 							"Bean with name '" + beanName + "' has been injected into other beans [" +
 							StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
 							"] in its raw version as part of a circular reference, but has eventually been " +
 							"wrapped. This means that said other beans do not use the final version of the " +
 							"bean. This is often the result of over-eager type matching - consider using " +
 							"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
 				}
 			}
 		}
 	}

 	// Register bean as disposable.
 	try {
 		registerDisposableBeanIfNecessary(beanName, bean, mbd);
 	}
 	catch (BeanDefinitionValidationException ex) {
 		throw new BeanCreationException(
 				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
 	}

 	return exposedObject;
 }
  1. AbstractAutowireCapableBeanFactory#populateBean() 方法内容比较多,本文重点关注其使用 InstantiationAwareBeanPostProcessor 后置处理器处理 Bean 属性的逻辑
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
 	if (bw == null) {
 		if (mbd.hasPropertyValues()) {
 			throw new BeanCreationException(
 					mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
 		}
 		else {
 			// Skip property population phase for null instance.
 			return;
 		}
 	}

 	// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
 	// state of the bean before properties are set. This can be used, for example,
 	// to support styles of field injection.
 	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
 		for (BeanPostProcessor bp : getBeanPostProcessors()) {
 			if (bp instanceof InstantiationAwareBeanPostProcessor) {
 				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
 				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
 					return;
 				}
 			}
 		}
 	}

 	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

 	int resolvedAutowireMode = mbd.getResolvedAutowireMode();
 	if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
 		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
 		// Add property values based on autowire by name if applicable.
 		if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
 			autowireByName(beanName, mbd, bw, newPvs);
 		}
 		// Add property values based on autowire by type if applicable.
 		if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
 			autowireByType(beanName, mbd, bw, newPvs);
 		}
 		pvs = newPvs;
 	}

 	boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
 	boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

 	PropertyDescriptor[] filteredPds = null;
 	if (hasInstAwareBpps) {
 		if (pvs == null) {
 			pvs = mbd.getPropertyValues();
 		}
 		for (BeanPostProcessor bp : getBeanPostProcessors()) {
 			if (bp instanceof InstantiationAwareBeanPostProcessor) {
 				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
 				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;
 			}
 		}
 	}
 	if (needsDepCheck) {
 		if (filteredPds == null) {
 			filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
 		}
 		checkDependencies(beanName, mbd, filteredPds, pvs);
 	}

 	if (pvs != null) {
 		applyPropertyValues(beanName, mbd, bw, pvs);
 	}
 }
  1. 2.1节中注册的 AutowiredAnnotationBeanPostProcessor 就实现了 InstantiationAwareBeanPostProcessor 接口,则此处 AutowiredAnnotationBeanPostProcessor#postProcessProperties() 将被触发调用,可以看到此处的关键处理有两步:
  1. 调用 AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata() 方法创建注入元数据对象 InjectionMetadata
  2. 调用 InjectionMetadata#inject() 方法进行数据注入
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;
 }
  1. AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata() 的处理是,先从缓存中获取 InjectionMetadata 对象,获取不到则调用 AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata() 构建
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);
 				}
 				metadata = buildAutowiringMetadata(clazz);
 				this.injectionMetadataCache.put(cacheKey, metadata);
 			}
 		}
 	}
 	return metadata;
 }
  1. AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata() 方法实现如下,可以看到这里会将目标类定义的字段 Field方法 Method 分别处理。具体逻辑是通过 AutowiredAnnotationBeanPostProcessor#findAutowiredAnnotation() 方法获取字段或者方法上标注的特定注解,如果能获取到说明需要处理依赖注入,则生成对应的 InjectedElement 实例,代表一个需要处理注入的元素
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<>();

		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;
				}
				boolean required = determineRequiredStatus(ann);
				currElements.add(new AutowiredFieldElement(field, required));
			}
		});

		ReflectionUtils.doWithLocalMethods(targetClass, method -> {
			Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
			if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
				return;
			}
			MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
			if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
				if (Modifier.isStatic(method.getModifiers())) {
					if (logger.isInfoEnabled()) {
						logger.info("Autowired annotation is not supported on static methods: " + method);
					}
					return;
				}
				if (method.getParameterCount() == 0) {
					if (logger.isInfoEnabled()) {
						logger.info("Autowired annotation should only be used on methods with parameters: " +
								method);
					}
				}
				boolean required = determineRequiredStatus(ann);
				PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
				currElements.add(new AutowiredMethodElement(method, required, pd));
			}
		});

		elements.addAll(0, currElements);
		targetClass = targetClass.getSuperclass();
	}
	while (targetClass != null && targetClass != Object.class);

	return InjectionMetadata.forElements(elements, clazz);
}
  1. AutowiredAnnotationBeanPostProcessor#findAutowiredAnnotation() 方法其实就是查看字段或者方法上是否存在指定的三个注解 @Autowired、@Value、@Inject
@Nullable
 private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
 	MergedAnnotations annotations = MergedAnnotations.from(ao);
 	for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
 		MergedAnnotation<?> annotation = annotations.get(type);
 		if (annotation.isPresent()) {
 			return annotation;
 		}
 	}
 	return null;
 }
  1. 经过以上步骤,Bean 对象需要处理依赖注入的元素都封装在了 InjectionMetadata 对象中,回到步骤4第2步InjectionMetadata#inject() 方法遍历其内部待填充属性的元素,调用其InjectedElement#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);
 		}
 	}
 }
  1. 本文以字段属性注入为例,AutowiredFieldElement#inject() 方法的实现如下,核心逻辑可分为两步:
  1. 调用 DefaultListableBeanFactory#resolveDependency() 从容器中获取字段的属性值
  2. field.set() 反射调用字段赋值方法,完成属性值的注入
@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 {
 				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);
 		}
 	}
  1. DefaultListableBeanFactory#resolveDependency() 会做常规的判断,核心是调用DefaultListableBeanFactory#doResolveDependency() 方法
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
		@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

	descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
	if (Optional.class == descriptor.getDependencyType()) {
		return createOptionalDependency(descriptor, requestingBeanName);
	}
	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 {
		Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
				descriptor, requestingBeanName);
		if (result == null) {
			result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
		}
		return result;
	}
 }
  1. DefaultListableBeanFactory#doResolveDependency() 方法重要流程分为以下几步:
  1. getAutowireCandidateResolver().getSuggestedValue(descriptor) 调用 2.1节提到的解析器 ContextAnnotationAutowireCandidateResolver#getSuggestedValue() 方法,将元素的注解中配置的字符串取出来。例如字段上标注了@Value("#{'${spring.data.users:nathan}'.split(',')}"),则这个步骤将取得字符串 #{'${spring.data.users:nathan}'.split(',')}
  2. 调用父类 AbstractBeanFactory#resolveEmbeddedValue() 方法解析字符串#{'${spring.data.users:nathan}'.split(',')}${} 包裹的部分,具体逻辑为使用键 spring.data.users 去容器中获取属性值,获取不到则使用冒号: 后默认的 nathan 作为值,方法返回后取得字符串 #{'nathan'.split(',')}
  3. 调用父类 AbstractBeanFactory#evaluateBeanDefinitionString() 方法使用 SpEL 表达式 解析字符串 #{'nathan'.split(',')},本例中实际是个字符串分割的操作,方法返回后获得一个字符串数组对象 [“nathan”]
  4. 调用类型转换器 TypeConverter#convertIfNecessary() 方法将以上步骤处理取得的值转换为目标字段的类型并返回
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
		@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

	InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
	try {
		Object shortcut = descriptor.resolveShortcut(this);
		if (shortcut != null) {
			return shortcut;
		}

		Class<?> type = descriptor.getDependencyType();
		Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
		if (value != null) {
			if (value instanceof String) {
				String strVal = resolveEmbeddedValue((String) value);
				BeanDefinition bd = (beanName != null && containsBean(beanName) ?
						getMergedBeanDefinition(beanName) : null);
				value = evaluateBeanDefinitionString(strVal, bd);
			}
			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...
				return (descriptor.getField() != null ?
						converter.convertIfNecessary(value, type, descriptor.getField()) :
						converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
			}
		}

		Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
		if (multipleBeans != null) {
			return multipleBeans;
		}

		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
		if (matchingBeans.isEmpty()) {
			if (isRequired(descriptor)) {
				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
			}
			return null;
		}

		String autowiredBeanName;
		Object instanceCandidate;

		if (matchingBeans.size() > 1) {
			autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
			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).
					return null;
				}
			}
			instanceCandidate = matchingBeans.get(autowiredBeanName);
		}
		else {
			// We have exactly one match.
			Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
			autowiredBeanName = entry.getKey();
			instanceCandidate = entry.getValue();
		}

		if (autowiredBeanNames != null) {
			autowiredBeanNames.add(autowiredBeanName);
		}
		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);
	}
}
  1. AbstractBeanFactory#resolveEmbeddedValue() 方法比较简单,就是遍历内部缓存的 StringValueResolver 列表,去获取目标属性值。在 2.2节步骤5 中,我们已经注册一个 lambda 表达式 作为 StringValueResolver 在容器内部,则此处会触发PropertySourcesPlaceholderConfigurer#processProperties() 中构造的表达式执行
public String resolveEmbeddedValue(@Nullable String value) {
	if (value == null) {
		return null;
	}
	String result = value;
	for (StringValueResolver resolver : this.embeddedValueResolvers) {
		result = resolver.resolveStringValue(result);
		if (result == null) {
			return null;
		}
	}
	return result;
}
  1. PropertySourcesPlaceholderConfigurer#processProperties() 中构造的表达式如下,可以看到此处最终使用目标键获取属性的操作是在调用的 PropertySourcesPropertyResolver#resolveRequiredPlaceholders() 方法中
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
		final ConfigurablePropertyResolver propertyResolver) throws BeansException {

	propertyResolver.setPlaceholderPrefix(this.placeholderPrefix);
	propertyResolver.setPlaceholderSuffix(this.placeholderSuffix);
	propertyResolver.setValueSeparator(this.valueSeparator);

	StringValueResolver valueResolver = strVal -> {
		String resolved = (this.ignoreUnresolvablePlaceholders ?
				propertyResolver.resolvePlaceholders(strVal) :
				propertyResolver.resolveRequiredPlaceholders(strVal));
		if (this.trimValues) {
			resolved = resolved.trim();
		}
		return (resolved.equals(this.nullValue) ? null : resolved);
	};

	......
}
  1. PropertySourcesPropertyResolver#resolveRequiredPlaceholders() 由其父类 AbstractPropertyResolver#resolveRequiredPlaceholders()实现,主要流程分为两步:
  1. 调用 AbstractPropertyResolver#createPlaceholderHelper() 方法创建 PropertyPlaceholderHelper对象
  2. 调用 AbstractPropertyResolver#doResolvePlaceholders() 方法,进而调用 PropertyPlaceholderHelper#replacePlaceholders() 方法获取属性值,处理原字符串替换
public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
	if (this.strictHelper == null) {
		this.strictHelper = createPlaceholderHelper(false);
	}
	return doResolvePlaceholders(text, this.strictHelper);
}

private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) {
	return helper.replacePlaceholders(text, this::getPropertyAsRawString);
}
  1. PropertyPlaceholderHelper#replacePlaceholders() 方法只是个入口,核心在 PropertyPlaceholderHelper#parseStringValue() 方法的实现,重要逻辑如下:
  1. 递归查找目标字符串中 ${} 包裹的字符串,直到最里层
  2. 使用分隔符 : 切割 ${} 包裹的字符串,将其前半部分作为入参调用 PlaceholderResolver#resolvePlaceholder() 方法取容器中的目标属性值(没有取到则将分隔符 : 后面的字符串作为目标值),替换掉原字符串部分
  3. 递归收束,最终返回给调用方的即为替换掉了 ${} 包裹内容的字符串
public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {
	Assert.notNull(value, "'value' must not be null");
	return parseStringValue(value, placeholderResolver, null);
}

protected String parseStringValue(
		String value, PlaceholderResolver placeholderResolver, @Nullable Set<String> visitedPlaceholders) {

	int startIndex = value.indexOf(this.placeholderPrefix);
	if (startIndex == -1) {
		return value;
	}

	StringBuilder result = new StringBuilder(value);
	while (startIndex != -1) {
		int endIndex = findPlaceholderEndIndex(result, startIndex);
		if (endIndex != -1) {
			String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex);
			String originalPlaceholder = placeholder;
			if (visitedPlaceholders == null) {
				visitedPlaceholders = new HashSet<>(4);
			}
			if (!visitedPlaceholders.add(originalPlaceholder)) {
				throw new IllegalArgumentException(
						"Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
			}
			// Recursive invocation, parsing placeholders contained in the placeholder key.
			placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
			// Now obtain the value for the fully resolved key...
			String propVal = placeholderResolver.resolvePlaceholder(placeholder);
			if (propVal == null && this.valueSeparator != null) {
				int separatorIndex = placeholder.indexOf(this.valueSeparator);
				if (separatorIndex != -1) {
					String actualPlaceholder = placeholder.substring(0, separatorIndex);
					String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
					propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
					if (propVal == null) {
						propVal = defaultValue;
					}
				}
			}
			if (propVal != null) {
				// Recursive invocation, parsing placeholders contained in the
				// previously resolved placeholder value.
				propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
				result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
				if (logger.isTraceEnabled()) {
					logger.trace("Resolved placeholder '" + placeholder + "'");
				}
				startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length());
			}
			else if (this.ignoreUnresolvablePlaceholders) {
				// Proceed with unprocessed value.
				startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
			}
			else {
				throw new IllegalArgumentException("Could not resolve placeholder '" +
						placeholder + "'" + " in value \"" + value + "\"");
			}
			visitedPlaceholders.remove(originalPlaceholder);
		}
		else {
			startIndex = -1;
		}
	}
	return result.toString();
}
  1. 回到步骤11第3步SpEL 表达式的解析入口为 AbstractBeanFactory#evaluateBeanDefinitionString() 方法,此处使用了 Spring 中 SpEL 表达式模块的相关 API, 本文不做进一步分析,有兴趣的读者可以自行搜索学习
protected Object evaluateBeanDefinitionString(@Nullable String value, @Nullable BeanDefinition beanDefinition) {
	if (this.beanExpressionResolver == null) {
		return value;
	}

	Scope scope = null;
	if (beanDefinition != null) {
		String scopeName = beanDefinition.getScope();
		if (scopeName != null) {
			scope = getRegisteredScope(scopeName);
		}
	}
	return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
 }
  1. 回到步骤11第4步,经过类型转换器将处理得到的属性值转换为目标字段的类型后,方法栈再回到步骤9第2步,一次属性注入的流程基本结束。类型转换的部分本文不再分析,读者有兴趣可以自行深入,至此 @Value 实现原理的分析暂告段落