Spring源码分析之@Autowired和@Value注解的处理

前言

Spring提供了@Autowired注解让我们可以很方便的注入依赖的Bean,提供了@Value注解可以让我们从properties文件或yml文件中注入属性值。

@Autowired注解使用

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;

public class TestAutowired {

  public static void main(String[] args) {
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    BeanDefinitionBuilder definitionBuilder = BeanDefinitionBuilder
        .genericBeanDefinition(UserService.class);
    beanFactory.registerBeanDefinition("userService", definitionBuilder.getBeanDefinition());
    definitionBuilder = BeanDefinitionBuilder
        .genericBeanDefinition(AddressService.class);
    beanFactory.registerBeanDefinition("addressService", definitionBuilder.getBeanDefinition());
    //进行属性装配的BeanPostProcessor
    AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor = new AutowiredAnnotationBeanPostProcessor();
    autowiredAnnotationBeanPostProcessor.setBeanFactory(beanFactory);
    beanFactory.addBeanPostProcessor(autowiredAnnotationBeanPostProcessor);
    UserService userService = (UserService) beanFactory
        .getBean("userService");
    userService.users();
  }

  public static class UserService {

    @Autowired
    private AddressService addressService;

    public void users() {
      System.out.println(addressService.getClass());
    }
  }

  public static class AddressService {

  }

}

为了更好的分析原理,没有使用扫描器(如扫描@Component注解)来自动注册BeanDefinition,向UserService注入AddressService属性。
核心为AutowiredAnnotationBeanPostProcessor,这是一个BeanPostProcessor,会在创建Bean的过程中进行属性装配。

@Qualifier注解使用

@Autowired注解会根据依赖的Bean的类型去容器中查找,如果找到多个Bean,Spring就不知道使用哪个,就会报错

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;

public class TestAutowiredQualifier {

  public static void main(String[] args) {
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    BeanDefinitionBuilder definitionBuilder = BeanDefinitionBuilder
        .genericBeanDefinition(UserService.class);
    beanFactory.registerBeanDefinition("userService", definitionBuilder.getBeanDefinition());
    definitionBuilder = BeanDefinitionBuilder
        .genericBeanDefinition(AddressService.class);
    beanFactory.registerBeanDefinition("addressService", definitionBuilder.getBeanDefinition());
    definitionBuilder = BeanDefinitionBuilder
        .genericBeanDefinition(AddressService2.class);
    beanFactory.registerBeanDefinition("addressService2", definitionBuilder.getBeanDefinition());
    //进行属性装配的BeanPostProcessor
    AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor = new AutowiredAnnotationBeanPostProcessor();
    autowiredAnnotationBeanPostProcessor.setBeanFactory(beanFactory);
    beanFactory.addBeanPostProcessor(autowiredAnnotationBeanPostProcessor);
    //设置自动装配Bean解析器,会找到最合适的依赖Bean
    beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
    UserService userService = (UserService) beanFactory
        .getBean("userService");
    userService.users();
  }

  public static class UserService {

    @Qualifier("addressService")
    @Autowired
    private IAddressService iAddressService;

    public void users() {
      System.out.println(iAddressService.getClass());
    }
  }

  public interface IAddressService {

  }

  public static class AddressService implements IAddressService {

  }

  public static class AddressService2 implements IAddressService {

  }

}

IAddressService有两个实现类,Spring在注入依赖时不知道具体使用哪个,所以使用了QualifierAnnotationAutowireCandidateResolver解析器来帮助我们选择,它会根据@Qualifier注解来过滤。

@Value注解使用

import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.env.StandardEnvironment;

public class TestAutowiredValue {

  public static void main(String[] args) {
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    BeanDefinitionBuilder definitionBuilder = BeanDefinitionBuilder
        .genericBeanDefinition(UserService.class);
    beanFactory.registerBeanDefinition("userService", definitionBuilder.getBeanDefinition());
    //进行属性装配的BeanPostProcessor
    AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor = new AutowiredAnnotationBeanPostProcessor();
    autowiredAnnotationBeanPostProcessor.setBeanFactory(beanFactory);
    beanFactory.addBeanPostProcessor(autowiredAnnotationBeanPostProcessor);
    //设置自动装配Bean解析器,会找到最合适的依赖Bean
    beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
    //设置属性解析器
    StandardEnvironment environment = new StandardEnvironment();
    beanFactory.addEmbeddedValueResolver(environment::resolvePlaceholders);
    UserService userService = (UserService) beanFactory.getBean("userService");
    userService.users();
  }

  public static class UserService {

    @Value(("${username:lisi}")) //username属性不存在,取默认值lisi
    private String userName;

    public void users() {
      System.out.println(userName);
    }
  }

}

注入@Value注解需要的属性值,格式为${name:defaultValue},关于environment,可以查看Spring源码分析之Environment

源码分析

Bean生命周期基本如下

我们在Spring源码分析之Bean生命周期 基础上继续分析Spring对属性依赖的处理。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
		//创建Bean实例
		BeanWrapper instanceWrapper = null;
		if (instanceWrapper == null) {
                        //创建Bean实例,会找到最合适的构造器,通过反射创建对象
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}
		//初始化Bean实例
		Object exposedObject = bean;
		try {
                        //Bean属性装配,AutowiredAnnotationBeanPostProcessor就是在这里被调用来处理@Autowired和@Value注解的
			populateBean(beanName, mbd, instanceWrapper);
                        //初始化Bean
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		return exposedObject;
	}

具体的处理逻辑就是在populateBean()方法

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		boolean continueWithPropertyPopulation = true;
                //在Bean实例化之后做一些操作,暂时不管
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

		if (!continueWithPropertyPopulation) {
			return;
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
                
                //处理自动装配模型相关(这里的自动是不需要使用@Autowired注解),默认不自动
		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			//按照name自动装配
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			//按照type自动装配
			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;
                                        //AutowiredAnnotationBeanPostProcessor就是在这里处理@Autowired注解和@Value注解的
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					pvs = pvsToUse;
				}
			}
		}
		//我们可以通过手动创建BeanDefinition时添加属性或者XML配置<Bean>中的property子节点
                //BeanDefinitionBuilder definitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(UserService.class);
                //definitionBuilder.addPropertyValue("username", "lisi");
		if (pvs != null) {
                        //将PropertyValues中的数据装配到Bean对象中
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

继续分析AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法

@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
                //根据@Autowired注解和@Value注解创建InjectionMetadata对象
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
                        //真正注入依赖的地方
			metadata.inject(bean, beanName, pvs);
		}
		return pvs;
	}

继续findAutowiringMetadata()方法

private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
		//缓存当前Bean的依赖注入信息
		String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
		//先查缓存,没有就创建,类似于双重锁判断实现的单例模式
		InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
		if (InjectionMetadata.needsRefresh(metadata, clazz)) {
			synchronized (this.injectionMetadataCache) {
				metadata = this.injectionMetadataCache.get(cacheKey);
				if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                                        //创建依赖注入的元数据对象
					metadata = buildAutowiringMetadata(clazz);
					this.injectionMetadataCache.put(cacheKey, metadata);
				}
			}
		}
		return metadata;
	}

继续buildAutowiringMetadata()方法

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
                //当前clazz不能是JDK本身的class,不能以java.开头,暂时不知道进行这个判断的原因
		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;
					}
                                        //是否必须,对于@Autowired注解,表示要注入的Bean在容器中是否存在,对于@Value注解无效
                                        //@Autowired注解提供了required字段配置,默认为true
					boolean required = determineRequiredStatus(ann);
					currElements.add(new AutowiredFieldElement(field, required));
				}
			});
                        //查找包含@Autowired注解或@Value注解的方法
			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())) {
						return;
					}
					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);
	}

@Value注解的required(必须性)是通过PropertyPlaceholderHelper(占位符解析器)的ignoreUnresolvablePlaceholders属性来决定的,默认false,表示必须存在。
InjectionMetadata对象创建完成之后,通过其inject()方法完成注入,每个InjectedElement对象都可以看做被@Autowired注解或@Value注解标记的属性或方法。

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);
			}
		}
	}

InjectedElement在这里是AutowiredFieldElement类型或者AutowiredMethodElement类型,这里我们只分析AutowiredFieldElement(属性注入)的实现

@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
			Field field = (Field) this.member;
			Object value; //缓存创建的DependencyDescriptor,暂时不知道什么情况下会使用到此缓存
			if (this.cached) {
                                //使用之前缓存的DependencyDescriptor
				value = resolvedCachedArgument(beanName, this.cachedFieldValue);
			}
			else {
				DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
				desc.setContainingClass(bean.getClass());
				Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
				TypeConverter typeConverter = beanFactory.getTypeConverter();
				try {  
                                        //委托给beanFactory来解析依赖
					value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
				}
			}
			if (value != null) {
                                //通过反射设置属性值
				ReflectionUtils.makeAccessible(field);
				field.set(bean, value);
			}
		}
	}

继续跟进去,注意,到了这里其实还没区分是注入Bean对象(@Autowired)还是注入属性值(@Value)

@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
                //方法的参数名称解析器
		descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
                //如果依赖的类型为工厂类型的,就包装一下,先跳过
		else {
                        //根据AutowireCandidateResolver(注入Bean选择器),默认为SimpleAutowireCandidateResolver类型
                        //getLazyResolutionProxyIfNecessary()方法获取懒加载的代理对象
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);
			if (result == null) {
                                //继续解析依赖,该方法返回的是依赖的Bean实例或者属性值(@Value注解)
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}

关于如何获取方法的参数名称,可以看java8中新增编译参数parameters入门
关于AutowireCandidateResolver(注入Bean选择器),默认为SimpleAutowireCandidateResolver类型。
如果想要支持@Qualifier注解,要使用QualifierAnnotationAutowireCandidateResolver类型。
如果想要支持@Lazy注解(懒加载),要使用ContextAnnotationAutowireCandidateResolver类型,如果开启了注解自动扫描(@ComponentScan),默认使用此类型,可以查看AnnotationConfigUtils的registerAnnotationConfigProcessors()方法。

@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
		try {
                        //如果依赖的Bean已经存在于容器中,直接从容器中取,直接getBean()
			Object shortcut = descriptor.resolveShortcut(this);
			if (shortcut != null) {
				return shortcut;
			}
			Class<?> type = descriptor.getDependencyType();
                        //又看到了AutowireCandidateResolver,默认类型SimpleAutowireCandidateResolver没有对getSuggestedValue()方法的有效实现
                        //QualifierAnnotationAutowireCandidateResolver重写了该方法,具体实现为查找@Value注解的值(终于看到了处理@Value注解的地方)
                        //如果当前是处理@Autowired注解,那么value为null
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
			if (value != null) {
                                //以上述的代码例子来说,value为字符串${username:lisi}
				if (value instanceof String) {
                                        //从environment中解析属性值,支持占位符解析
                                        //代码中我们使用的lambda表达式(environment::resolvePlaceholders)来创建StringValueResolver对象
					String strVal = resolveEmbeddedValue((String) value);
					BeanDefinition bd = (beanName != null && containsBean(beanName) ?
							getMergedBeanDefinition(beanName) : null);
                                        //再交给SpringEL表达式解析器处理,如果strVal为#{123+456},处理之后为579
					value = evaluateBeanDefinitionString(strVal, bd);
				}
                                //类型转换,至此@Value注解的处理就结束了
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				try {
					return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
				}
			}
                        //处理依赖类型为复合类型的情况,如Collection,Map,Array等。如果为Collection类型,那么必须为接口,不能是具体的实现类如ArrayList,原因暂时不知道
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}
                        //从容器中查询匹配的依赖,默认根据type来匹配,如果配置了@Qualifier注解,就根据name和type匹配,
                        //QualifierAnnotationAutowireCandidateResolver就是通过重写isAutowireCandidate()方法来支持@Qualifier注解的
                        //这个方法也是很复杂,就先不跟了
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (matchingBeans.isEmpty()) {
                                //如果未找到匹配的Bean,且配置为required,就抛出异常
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}

			String autowiredBeanName;
			Object instanceCandidate;

			if (matchingBeans.size() > 1) {
                                //如果有多个匹配的依赖,根据一些策略来决定使用哪个
                                //取BeanDefinition设置为primary(可以通过@Primary注解配置)的那个,如果都没有
                                //再通过获取priority值(通过javax.annotation.Priority注解配置),取优先级最高的,值越小优先级越高
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
                                //如果还是决定不了使用哪个依赖,抛出异常
				if (autowiredBeanName == null) {
					if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
						return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
					}
					else {
						return null;
					}
				}
				instanceCandidate = matchingBeans.get(autowiredBeanName);
			}
			else {
				//执行到这说明已经找到了唯一匹配的依赖
				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还不是依赖的Bean实例,只是Bean的Class,再从容器中找到Bean实例,至此@Autowired注解处理完毕
				instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
			}
                        Object result = instanceCandidate;
			return result;
		}
	}

分析总结

  1. 在Bean创建过程中的属性装配阶段,委托给AutowiredAnnotationBeanPostProcessor处理属性装配
  2. AutowiredAnnotationBeanPostProcessor查找Class中包含@Autowired注解和@Value注解的属性和方法
  3. 以属性注入为例,委托给BeanFactory解析出要注入的对象
  4. BeanFactory从容器中根据name和type查询到所有匹配的依赖,选择出最匹配的。
  5. 通过反射设置到属性中

核心处理类有
AutowiredAnnotationBeanPostProcessor,根据指定的注解类型查找属性和方法,委托给BeanFactory解析出依赖对象。
BeanFactory,解析出具体的依赖对象,委托QualifierAnnotationAutowireCandidateResolver来过滤出最合适的依赖对象和查找到@Value注解的原始值。根据原始值从environment中解析出属性值。
QualifierAnnotationAutowireCandidateResolver,通过处理@Qualifier注解来过滤依赖对象,查找到@Value注解的原始值。

posted @ 2022-05-08 13:10  strongmore  阅读(496)  评论(0编辑  收藏  举报