3.springboot-@Autowired和@Value工作原理

Pingszi發表於2020-11-18

1.簡介

A.名詞說明

  • spring bean生命週期
  • 複合建構函式(synthetic):由編譯器引入的建構函式,主要用於JVM內部使用;
  • 橋接方法(bridge):由編譯器引入的方法,主要用於JVM內部使用;

B.@Autowired與@Value功能

  • @Autowired與@Value功能基本相同,都可以自動裝配bean;
  • @Value除了可以自動裝配bean外,還可以自動裝配配置引數。裝配配置引數時,也可以配置引數寫在方法上;
@Component
public class MyAutowiredDemo {
    @Value("user")
    public Object configInt;

    @Value("${spring.test.config-int}")
    public void test(Object configInt) {
        System.out.println(configInt);
    }
}

2.InjectionMetadata注入後設資料

InjectionMetadata(類的注入後設資料),描述每個依賴spring注入的java類,以及所有需要注入member(Member是java欄位、方法和建構函式的父類)的相關資訊;

//**類的注入後設資料(描述每個依賴spring注入的java類,以及所有需要注入member的相關資訊)
public class InjectionMetadata {

	//**空後設資料
	public static final InjectionMetadata EMPTY = new InjectionMetadata(Object.class, Collections.emptyList()) {
		@Override
		protected boolean needsRefresh(Class<?> clazz) {
			return false;
		}
		@Override
		public void checkConfigMembers(RootBeanDefinition beanDefinition) {
		}
		@Override
		public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) {
		}
		@Override
		public void clear(@Nullable PropertyValues pvs) {
		}
	};

    //**注入的目標類
	private final Class<?> targetClass;
    //**目標類所有注入元素的集合
	private final Collection<InjectedElement> injectedElements;
    //**檢查的注入元素集合
	@Nullable
	private volatile Set<InjectedElement> checkedElements;

    //**構造方法
	public InjectionMetadata(Class<?> targetClass, Collection<InjectedElement> elements) {
		this.targetClass = targetClass;
		this.injectedElements = elements;
	}

    //**檢查是否需要重新整理
	protected boolean needsRefresh(Class<?> clazz) {
		return this.targetClass != clazz;
	}
    
    //**遍歷注入元素集合檢查member是否註冊到externallyManagedConfigMembers(spring管理的配置成員集合)
	public void checkConfigMembers(RootBeanDefinition beanDefinition) {
		Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
		for (InjectedElement element : this.injectedElements) {
		    //**如注入元素對應的member沒有註冊到externallyManagedConfigMembers,則註冊
		    //**然後把注入元素新增到checkedElements
			Member member = element.getMember();
			if (!beanDefinition.isExternallyManagedConfigMember(member)) {
				beanDefinition.registerExternallyManagedConfigMember(member);
				checkedElements.add(element);
				if (logger.isTraceEnabled()) {
					logger.trace("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
				}
			}
		}
		this.checkedElements = checkedElements;
	}
    
    //**遍歷注入元素集合,呼叫注入元素的inject方法注入member依賴的bean
	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);
			}
		}
	}

	//**遍歷注入元素集合,呼叫注入元素的clearPropertySkipping方法清除所有已經注入的member
	public void clear(@Nullable PropertyValues pvs) {
		Collection<InjectedElement> checkedElements = this.checkedElements;
		Collection<InjectedElement> elementsToIterate =
				(checkedElements != null ? checkedElements : this.injectedElements);
		if (!elementsToIterate.isEmpty()) {
			for (InjectedElement element : elementsToIterate) {
				element.clearPropertySkipping(pvs);
			}
		}
	}

    //**靜態方法,建立InjectionMetadata物件
	public static InjectionMetadata forElements(Collection<InjectedElement> elements, Class<?> clazz) {
		return (elements.isEmpty() ? InjectionMetadata.EMPTY : new InjectionMetadata(clazz, elements));
	}

	//**靜態方法,檢查是否需要重新整理
	public static boolean needsRefresh(@Nullable InjectionMetadata metadata, Class<?> clazz) {
		return (metadata == null || metadata.needsRefresh(clazz));
	}

    //**注入元素(描述每個依賴spring注入的member相關資訊)
	public abstract static class InjectedElement {
        //**member
		protected final Member member;
        //**member是否是欄位
		protected final boolean isField;
        //**member的屬性描述器
		@Nullable
		protected final PropertyDescriptor pd;
        //**是否跳過
		@Nullable
		protected volatile Boolean skip;
        
        //**構造方法
		protected InjectedElement(Member member, @Nullable PropertyDescriptor pd) {
			this.member = member;
			this.isField = (member instanceof Field);
			this.pd = pd;
		}
        
        //**獲取member依賴spring注入的bean型別
		protected final Class<?> getResourceType() {
		    //**如果是欄位,則直接返回欄位的型別
			if (this.isField) {
				return ((Field) this.member).getType();
			}
			//**如果包含屬性描述器,則使用屬性描述器獲取型別
			else if (this.pd != null) {
				return this.pd.getPropertyType();
			}
			else {  //**如果是方法,則返回第一個引數的型別
				return ((Method) this.member).getParameterTypes()[0];
			}
		}
        
        //**檢查指定類是否可以注入到member(指定類和member依賴bean是否存在繼承關係)
		protected final void checkResourceType(Class<?> resourceType) {
			if (this.isField) {
				Class<?> fieldType = ((Field) this.member).getType();
				if (!(resourceType.isAssignableFrom(fieldType) || fieldType.isAssignableFrom(resourceType))) {
					throw new IllegalStateException("Specified field type [" + fieldType +
							"] is incompatible with resource type [" + resourceType.getName() + "]");
				}
			}
			else {
				Class<?> paramType =
						(this.pd != null ? this.pd.getPropertyType() : ((Method) this.member).getParameterTypes()[0]);
				if (!(resourceType.isAssignableFrom(paramType) || paramType.isAssignableFrom(resourceType))) {
					throw new IllegalStateException("Specified parameter type [" + paramType +
							"] is incompatible with resource type [" + resourceType.getName() + "]");
				}
			}
		}

		//**注入member依賴的bean(實際沒有使用,使用的其子類AutowiredFieldElement和AutowiredMethodElement的重寫方法)
		protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
				throws Throwable {
            //**如果是欄位,直接設定欄位的值
			if (this.isField) {
				Field field = (Field) this.member;
				ReflectionUtils.makeAccessible(field);
				//**getResourceToInject(target, requestingBeanName)獲取注入的bean
				field.set(target, getResourceToInject(target, requestingBeanName));
			}
			else {
			    //**如果已經注入,則跳過
				if (checkPropertySkipping(pvs)) {
					return;
				}
				//**如果是方法,呼叫方法
				try {
					Method method = (Method) this.member;
					ReflectionUtils.makeAccessible(method);
					//**getResourceToInject(target, requestingBeanName)獲取注入的bean
					method.invoke(target, getResourceToInject(target, requestingBeanName));
				}
				catch (InvocationTargetException ex) {
					throw ex.getTargetException();
				}
			}
		}

		//**檢查是否已經注入
		protected boolean checkPropertySkipping(@Nullable PropertyValues pvs) {
			Boolean skip = this.skip;
			if (skip != null) {
				return skip;
			}
			if (pvs == null) {
				this.skip = false;
				return false;
			}
			synchronized (pvs) {
				skip = this.skip;
				if (skip != null) {
					return skip;
				}
				if (this.pd != null) {
				    //**包含在已經處理過的集合(processedProperties)中,則返回true
					if (pvs.contains(this.pd.getName())) {
						this.skip = true;
						return true;
					}
					//**否則,在已經處理過的集合中註冊,並返回false
					else if (pvs instanceof MutablePropertyValues) {
						((MutablePropertyValues) pvs).registerProcessedProperty(this.pd.getName());
					}
				}
				this.skip = false;
				return false;
			}
		}

		//**清除已經注入的member
		protected void clearPropertySkipping(@Nullable PropertyValues pvs) {
			if (pvs == null) {
				return;
			}
			synchronized (pvs) {
				if (Boolean.FALSE.equals(this.skip) && this.pd != null && pvs instanceof MutablePropertyValues) {
					((MutablePropertyValues) pvs).clearProcessedProperty(this.pd.getName());
				}
			}
		}

		//**獲取注入的物件,這裡返回null,需用子類實現
		@Nullable
		protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
			return null;
		}

        ...equals and hashCode and toString方法
	}
}

3.AutowiredAnnotationBeanPostProcessor(自動裝配處理器)

注意(重點)

A.處理邏輯

  • 首先處理@Lookup註解並獲取候選的建構函式(包括父類上的@Lookup)。注意,這裡只是選擇了匹配的建構函式,有可能有多個,具體呼叫哪個建構函式邏輯在ConstructorResolver.autowireConstructor(),不在本篇深究;
  • 然後把依賴spring注入的member資訊註冊到RootBeanDefinition的externallyManagedConfigMembers(spring管理的配置成員集合);
  • 最後把bean及其依賴注入的bean的關係註冊到DefaultSingletonBeanRegistryt的dependentBeanMap和dependenciesForBeanMap。然後設定注入的值(如果是欄位,直接賦值,如果是方法,呼叫方法);

B.自定義自動裝配註解

自定一個自動裝配註解@MyAutowired,功能同解@Autowired

//1.自定義解@MyAutowired註解
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAutowired {

    //**required引數名也可以自定義
    boolean required() default true;

}

//2.使MyAutowired註解生效
@Component
public class MyAutowiredAnnotationBeanPostProcessor extends AutowiredAnnotationBeanPostProcessor {

    public MyAutowiredAnnotationBeanPostProcessor(){
        super.setAutowiredAnnotationTypes(Set.of(Autowired.class, Value.class, MyAutowired.class));
    }
}

//3.使用示例
@Component
public class MyAutowiredDemo {

    @MyAutowired
    private User user;

    public void hello(){
        System.out.println(user.getClass());
    }
}

C.處理規則

構造方法注入:

  • 如果required=true,只能標註一個@Autowired
  • 如果required=false,可標註多個@Autowired,且匹配項最多的建構函式會生效
  • 如果沒有匹配到任何一個建構函式,則預設的建構函式會生效
  • 如果只有一個建構函式,則這個建構函式會生效(無論有沒有標註@Autowired)
  • 建構函式不需要為public

欄位注入:

  • 欄位在構造方法注入之後,在配置方法注入之前呼叫
  • 欄位不需要為public

方法注入

  • 配置方法可以有任意名稱和任意數量的引數,spring會從容器中匹配並注入這些引數
  • setter方法是配置方法的特例,spring並沒有要求配置方法一定是setter方法
  • 配置方法不需要為public

xml配置注入

  • 預設情況下,AutowiredAnnotationBeanPostProcessor會註冊context:annotation-config和context:component-scan標籤
  • 可指定自定義的AutowiredAnnotationBeanPostProcessor刪除或者關閉預設的註解配置
  • 注意:註解注入會在xml注入之前執行。後一種配置會覆蓋前一種配置

Lookup方法

  • @Lookup會在執行查詢需要注入的引數(如果引數不是單例的,這會很有用。等同型別安全的getBean方法)

原始碼

  • InstantiationAwareBeanPostProcessorAdapter:SmartInstantiationAwareBeanPostProcessor(智慧例項化處理器)介面介面卡(空實現),其子類只需要實現關注的方法,而不用把所有的方法都實現;
  • MergedBeanDefinitionPostProcessor:合併Bean定義後置處理器;
  • PriorityOrdered:優先的Ordered序列,PriorityOrdered優先順序總是在Ordered之前(無論order值是多少);
  • BeanFactoryAware:獲取spring上下文中的BeanFactory;
  • 執行順序:
    • BeanFactory.setBeanFactory()
    • PriorityOrdered.getOrder()
    • InstantiationAwareBeanPostProcessorAdapter.determineCandidateConstructors():處理@Lookup註解並獲取候選的建構函式(包括父類上的@Lookup);
    • MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition():註冊需要注入的member;
    • InstantiationAwareBeanPostProcessorAdapter.postProcessProperties():執行注入bean的邏輯(包括父類上的注入註解);
    • MergedBeanDefinitionPostProcessor.resetBeanDefinition():重置bean定義後,在快取中刪除注入資料;
/**
 * 實現自動裝配:註解,欄位,setter方法和配置方法
 * 通過註解檢測需要注入的成員。預設註解包括@Autowired和@Value,並且支援JSR-330的@Inject(同@Autowired)
 * 
 * 構造方法注入:
 * 如果required=true,只能標註一個@Autowired
 * 如果required=false,可標註多個@Autowired,且匹配項最多的建構函式會生效
 * 如果沒有匹配到任何一個建構函式,則預設的建構函式會生效
 * 如果只有一個建構函式,則這個建構函式會生效(無論有沒有標註@Autowired)
 * 建構函式不需要為public
 *
 * 欄位注入:
 * 欄位在構造方法注入之後,在配置方法注入之前呼叫
 * 欄位不需要為public
 *
 * 方法注入
 * 配置方法可以有任意名稱和任意數量的引數,spring會從容器中匹配並注入這些引數
 * setter方法是配置方法的特例,spring並沒有要求配置方法一定是setter方法
 * 配置方法不需要為public
 *
 * xml配置注入
 * 預設情況下,AutowiredAnnotationBeanPostProcessor會註冊context:annotation-config和context:component-scan標籤
 * 可指定自定義的AutowiredAnnotationBeanPostProcessor刪除或者關閉預設的註解配置
 *
 * 注意:註解注入會在xml注入之前執行。後一種配置會覆蓋前一種配置
 *
 * Lookup方法
 * @Lookup會在執行查詢需要注入的引數(如果引數不是單例的,這會很有用。等同型別安全的getBean方法)
 */
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
		implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
	//**處理的注入註解
	private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
    //**表示required引數的引數名
	private String requiredParameterName = "required";
    //**表示required引數的預設值
	private boolean requiredParameterValue = true;
    //**預設的執行順序
	private int order = Ordered.LOWEST_PRECEDENCE - 2;
    //**beanFactory
	@Nullable
	private ConfigurableListableBeanFactory beanFactory;
    //**快取處理過@Lookup註解的bean名稱
	private final Set<String> lookupMethodsChecked = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
    //**快取指定類候選的建構函式
	private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache = new ConcurrentHashMap<>(256);
    //**快取注入的後設資料
	private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);

    //**預設處理的自動裝配註解為@Autowired和@Value,並且支援@Inject
	public AutowiredAnnotationBeanPostProcessor() {
		this.autowiredAnnotationTypes.add(Autowired.class);
		this.autowiredAnnotationTypes.add(Value.class);
		try {
			this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
					ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
			logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - simply skip.
		}
	}
    
    //**指定處理的自動裝配註解
	public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType) {
		Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null");
		this.autowiredAnnotationTypes.clear();
		this.autowiredAnnotationTypes.add(autowiredAnnotationType);
	}

	//**指定多個處理的自動裝配註解
	public void setAutowiredAnnotationTypes(Set<Class<? extends Annotation>> autowiredAnnotationTypes) {
		Assert.notEmpty(autowiredAnnotationTypes, "'autowiredAnnotationTypes' must not be empty");
		this.autowiredAnnotationTypes.clear();
		this.autowiredAnnotationTypes.addAll(autowiredAnnotationTypes);
	}

	//**指定表示required引數的引數名
	public void setRequiredParameterName(String requiredParameterName) {
		this.requiredParameterName = requiredParameterName;
	}

	//**指定表示required引數的引數值
	public void setRequiredParameterValue(boolean requiredParameterValue) {
		this.requiredParameterValue = requiredParameterValue;
	}

    //**設定執行順序
	public void setOrder(int order) {
		this.order = order;
	}
    
    //**實現PriorityOrdered,獲取執行順序
	@Override
	public int getOrder() {
		return this.order;
	}

    //**實現BeanFactoryAware,獲取beanFactory
	@Override
	public void setBeanFactory(BeanFactory beanFactory) {
		if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
			throw new IllegalArgumentException(
					"AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory: " + beanFactory);
		}
		this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
	}

    //**實現MergedBeanDefinitionPostProcessor
    //**如果存在需要注入的member,則註冊到externallyManagedConfigMembers(spring管理的配置成員集合)
	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
	    //**獲取注入後設資料
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		//**如果存在需要注入的member,把注入元素註冊到externallyManagedConfigMembers(spring管理的配置成員集合)
		metadata.checkConfigMembers(beanDefinition);
	}
    
    //**實現MergedBeanDefinitionPostProcessor,重置bean定義後,在快取中刪除注入資料;
	@Override
	public void resetBeanDefinition(String beanName) {
		this.lookupMethodsChecked.remove(beanName);
		this.injectionMetadataCache.remove(beanName);
	}
    
    //**實現InstantiationAwareBeanPostProcessorAdapter,處理@Lookup註解並獲取候選的建構函式
    //**如果required=true,則只能有一個候選建構函式
    //**如果required=false,則全部都為候選建構函式
    //**如果只有一個建構函式且包含引數,則這個建構函式為候選建構函式(無論有沒有標註@Autowired)
	@Override
	@Nullable
	public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
			throws BeanCreationException {
        //**處理當前類及其父類@Lookup註解(spring會動態生成子類並重寫/實現被註解的方法),並快取到lookupMethodsChecked中
		if (!this.lookupMethodsChecked.contains(beanName)) {
			if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
				try {
					Class<?> targetClass = beanClass;
					do {
						ReflectionUtils.doWithLocalMethods(targetClass, method -> {
							Lookup lookup = method.getAnnotation(Lookup.class);
							if (lookup != null) {
								Assert.state(this.beanFactory != null, "No BeanFactory available");
								LookupOverride override = new LookupOverride(method, lookup.value());
								try {
									RootBeanDefinition mbd = (RootBeanDefinition)
											this.beanFactory.getMergedBeanDefinition(beanName);
									mbd.getMethodOverrides().addOverride(override);
								}
								catch (NoSuchBeanDefinitionException ex) {
									throw new BeanCreationException(beanName,
											"Cannot apply @Lookup to beans without corresponding bean definition");
								}
							}
						});
						targetClass = targetClass.getSuperclass();
					}
					while (targetClass != null && targetClass != Object.class);

				}
				catch (IllegalStateException ex) {
					throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
				}
			}
			this.lookupMethodsChecked.add(beanName);
		}

		//**從快取中獲取當前類的候選建構函式
		Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
		//**快取中不存在,則獲取
		if (candidateConstructors == null) {
			//**加鎖
			synchronized (this.candidateConstructorsCache) {
				candidateConstructors = this.candidateConstructorsCache.get(beanClass);
				if (candidateConstructors == null) {
				    
				    //**獲取所有建構函式
					Constructor<?>[] rawCandidates;
					try {
						rawCandidates = beanClass.getDeclaredConstructors();
					}
					catch (Throwable ex) {
						throw new BeanCreationException(beanName,
								"Resolution of declared constructors on bean Class [" + beanClass.getName() +
								"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
					}
					//**存放候選建構函式
					List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
					//**required=true的建構函式
					Constructor<?> requiredConstructor = null;
					//**預設的無參建構函式
					Constructor<?> defaultConstructor = null;
					//**Kotlin中的primary建構函式,java直接返回null
					Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
					//**非Synthetic建構函式的數量(synthetic是由編譯器引入的建構函式,主要用於JVM內部使用)
					int nonSyntheticConstructors = 0;
					
					//**遍歷所有建構函式
					for (Constructor<?> candidate : rawCandidates) {
					    //**記錄非Synthetic建構函式的數量
						if (!candidate.isSynthetic()) {
							nonSyntheticConstructors++;
						}
						//**java這裡為null
						else if (primaryConstructor != null) {
							continue;
						}
						//**查詢是否包含@Autowired和@Value等注入註解
						MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
						//**如果不包含注入註解,則獲取當前類的使用者類(如果當前類為spring生成的動態代理類,則會獲取到當前類代理的類)建構函式的注入註解
						if (ann == null) {
							Class<?> userClass = ClassUtils.getUserClass(beanClass);
							if (userClass != beanClass) {
								try {
									Constructor<?> superCtor =
											userClass.getDeclaredConstructor(candidate.getParameterTypes());
									ann = findAutowiredAnnotation(superCtor);
								}
								catch (NoSuchMethodException ex) {
									// Simply proceed, no equivalent superclass constructor found...
								}
							}
						}
						
						//**如果包含注入註解,驗證如果required=true時只能標註一個@Autowired,並新增到候選建構函式集合中
						if (ann != null) {
							if (requiredConstructor != null) {
								throw new BeanCreationException(beanName,
										"Invalid autowire-marked constructor: " + candidate +
										". Found constructor with 'required' Autowired annotation already: " +
										requiredConstructor);
							}
							//**獲取當前建構函式required的值
							boolean required = determineRequiredStatus(ann);
							if (required) {
								if (!candidates.isEmpty()) {
									throw new BeanCreationException(beanName,
											"Invalid autowire-marked constructors: " + candidates +
											". Found constructor with 'required' Autowired annotation: " +
											candidate);
								}
								requiredConstructor = candidate;
							}
							candidates.add(candidate);
						}
						else if (candidate.getParameterCount() == 0) { //**否則如果引數為0,則為預設建構函式
							defaultConstructor = candidate;
						}
					}
					
					//**如果候選建構函式不為空,並且required=true的建構函式為空,則把預設建構函式新增到候選建構函式集合中
					if (!candidates.isEmpty()) {
						if (requiredConstructor == null) {
							if (defaultConstructor != null) {
								candidates.add(defaultConstructor);
							}
							else if (candidates.size() == 1 && logger.isInfoEnabled()) {
								logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
										"': single autowire-marked constructor flagged as optional - " +
										"this constructor is effectively required since there is no " +
										"default constructor to fall back to: " + candidates.get(0));
							}
						}
						candidateConstructors = candidates.toArray(new Constructor<?>[0]);
					}
				    //**如果只有一個建構函式,則這個建構函式會生效(無論有沒有標註@Autowired)
					else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
						candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
					}
					//**針對Kotlin中的primary建構函式
					else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
							defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
						candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
					}
					else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
						candidateConstructors = new Constructor<?>[] {primaryConstructor};
					}
					else { //**否則返回空建構函式陣列
						candidateConstructors = new Constructor<?>[0];
					}
					//**快取到candidateConstructorsCache中
					this.candidateConstructorsCache.put(beanClass, candidateConstructors);
				}
			}
		}
		return (candidateConstructors.length > 0 ? candidateConstructors : null);
	}
    
    //**實現InstantiationAwareBeanPostProcessorAdapter.postProcessProperties(),執行注入bean的邏輯
	@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
	    //**獲取當前bean的注入後設資料
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {//**執行注入(欄位使用使用AutowiredFieldElement.inject(),方法使用AutowiredMethodElement的.inject())
			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;
	}
    
    //**過時,以postProcessProperties為準
	@Deprecated
	@Override
	public PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {

		return postProcessProperties(pvs, bean, beanName);
	}

	//**指定bean的注入,邏輯基本和postProcessProperties一樣,執行專案沒發現有呼叫
	public void processInjection(Object bean) throws BeanCreationException {
		Class<?> clazz = bean.getClass();
		InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null);
		try {
			metadata.inject(bean, null, null);
		}
		catch (BeanCreationException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					"Injection of autowired dependencies failed for class [" + clazz + "]", ex);
		}
	}

    //**獲取指定bean的注入後設資料
	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());
		//**從快取中獲取注入後設資料
		InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
		//**如果metadata為空,則重新構造metadata,如果metadata的目標類不是傳入的clazz,則清除注入資料,然後重新構造metadata
		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
					metadata = buildAutowiringMetadata(clazz);
					//**快取到injectionMetadataCache中
					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<>();
            
            //**遍歷獲取類的欄位注入元素
			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;
					}
					//**獲取required的值
					boolean required = determineRequiredStatus(ann);
					//**建立注入元素並存放到currElements中
					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);
				//**如果方法包含注入註解 && 屬於指定clazz類(繼承的方法也算)
				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);
						}
					}
					//**獲取required的值
					boolean required = determineRequiredStatus(ann);
					//**獲取方法的屬性描述器
					PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
					//**建立注入元素並存放到currElements中
					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);
	}
    
    //**查詢member上的注入註解
	@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;
	}

	//**獲取注入配置的required的值
	@SuppressWarnings({"deprecation", "cast"})
	protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
		// The following (AnnotationAttributes) cast is required on JDK 9+.
		return determineRequiredStatus((AnnotationAttributes)
				ann.asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
	}

	//**過時,獲取注入配置的required的值
	@Deprecated
	protected boolean determineRequiredStatus(AnnotationAttributes ann) {
		return (!ann.containsKey(this.requiredParameterName) ||
				this.requiredParameterValue == ann.getBoolean(this.requiredParameterName));
	}

	//**根據類物件查詢注入的候選bean
	protected <T> Map<String, T> findAutowireCandidates(Class<T> type) throws BeansException {
		if (this.beanFactory == null) {
			throw new IllegalStateException("No BeanFactory configured - " +
					"override the getBeanOfType method or specify the 'beanFactory' property");
		}
		return BeanFactoryUtils.beansOfTypeIncludingAncestors(this.beanFactory, type);
	}

	//**註冊bean及其依賴注入的bean
	private void registerDependentBeans(@Nullable String beanName, Set<String> autowiredBeanNames) {
		if (beanName != null) {
			for (String autowiredBeanName : autowiredBeanNames) {
				if (this.beanFactory != null && this.beanFactory.containsBean(autowiredBeanName)) {
					this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
				}
				if (logger.isTraceEnabled()) {
					logger.trace("Autowiring by type from bean name '" + beanName +
							"' to bean named '" + autowiredBeanName + "'");
				}
			}
		}
	}

	//**解析指定的快取方法引數/欄位值
	@Nullable
	private Object resolvedCachedArgument(@Nullable String beanName, @Nullable Object cachedArgument) {
		if (cachedArgument instanceof DependencyDescriptor) {
			DependencyDescriptor descriptor = (DependencyDescriptor) cachedArgument;
			Assert.state(this.beanFactory != null, "No BeanFactory available");
			return this.beanFactory.resolveDependency(descriptor, beanName, null, null);
		}
		else {
			return cachedArgument;
		}
	}

    //**注入元素(描述每個依賴spring注入的欄位相關資訊)
	private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
        //**required
		private final boolean required;
        //**是否已經快取欄位注入的值
		private volatile boolean cached = false;
        //**快取欄位注入的值
		@Nullable
		private volatile Object cachedFieldValue;

		public AutowiredFieldElement(Field field, boolean required) {
			super(field, null);
			this.required = required;
		}
        
        //**注入
		@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 {
			    //**獲取注入的bean
				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獲取配置的引數值,則此處獲取的是配置的值,autowiredBeanNames會為空
					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) { //**如果注入的bean存在 || required = true
							this.cachedFieldValue = desc;  //**快取注入的bean
							//**註冊bean及其依賴注入的bean
							registerDependentBeans(beanName, autowiredBeanNames); 
							//**如果匹配的依賴bean只有一個,則封裝為ShortcutDependencyDescriptor,並快取
							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);
			}
		}
	}

	//**注入元素(描述每個依賴spring注入的方法相關資訊)
	private class AutowiredMethodElement extends InjectionMetadata.InjectedElement {
        //**required
		private final boolean required;
        //**是否已經快取方法注入的值
		private volatile boolean cached = false;
        //**快取方法注入的值
		@Nullable
		private volatile Object[] cachedMethodArguments;

		public AutowiredMethodElement(Method method, boolean required, @Nullable PropertyDescriptor pd) {
			super(method, pd);
			this.required = required;
		}
        
        //**注入
		@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) {//**如果已經快取方法注入的值,則直接從快取中解析
				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();
				//**遍歷方法的所有引數,獲取注入的bean
				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 {
					    //**如果是@value獲取配置的引數值,則此處獲取的是配置的值,autowiredBeanNames會為空
						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);
							//**註冊bean及其依賴注入的bean
							registerDependentBeans(beanName, autowiredBeans);
							//**如果每個引數匹配的依賴bean都只有一個,則封裝為ShortcutDependencyDescriptor,並快取
							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();
				}
			}
		}
        
        //**遍歷解析快取引數
		@Nullable
		private Object[] resolveCachedArguments(@Nullable String beanName) {
			Object[] cachedMethodArguments = this.cachedMethodArguments;
			if (cachedMethodArguments == null) {
				return null;
			}
			Object[] arguments = new Object[cachedMethodArguments.length];
			for (int i = 0; i < arguments.length; i++) {
				arguments[i] = resolvedCachedArgument(beanName, cachedMethodArguments[i]);
			}
			return arguments;
		}
	}

    //**注入依賴描述器
	@SuppressWarnings("serial")
	private static class ShortcutDependencyDescriptor extends DependencyDescriptor {

		private final String shortcut;

		private final Class<?> requiredType;

		public ShortcutDependencyDescriptor(DependencyDescriptor original, String shortcut, Class<?> requiredType) {
			super(original);
			this.shortcut = shortcut;
			this.requiredType = requiredType;
		}

		@Override
		public Object resolveShortcut(BeanFactory beanFactory) {
			return beanFactory.getBean(this.shortcut, this.requiredType);
		}
	}

}

相關文章