Spring在属性填充过程中,需要判断属性和方法是否为一个注入点,然后根据注入点找到对象赋值或者创建Bean进行赋值。
1、最外层属性赋值
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;
}
2、区分方法和属性,分开注入
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);
}
}
}
3、字段注入的方式
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
try {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
else {
value = resolveFieldValue(field, bean, beanName);
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
- org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#resolveFieldValue
- 如果属性是一个懒加载的对象,会返回一个代理对象。
- 尝试从单例池中获取,如果存在则直接返回。
- 判断属性上是否含有@Vlaue注解(org.springframework.beans.factory.support.AutowireCandidateResolver#getSuggestedValue)
- 根据类型查找获选的BeanName(org.springframework.beans.factory.BeanFactoryUtils#beanNamesForTypeIncludingAncestors(org.springframework.beans.factory.ListableBeanFactory, java.lang.Class<?>, boolean, boolean))。
- 检查BeanDefinfition的autowieCandiateResolver(属性org.springframework.beans.factory.support.SimpleAutowireCandidateResolver#isAutowireCandidate)。
- 检查BeanDefinition的beanClass属性和当前的注入点type是否匹配。(org.springframework.beans.factory.support.GenericTypeAwareAutowireCandidateResolver#checkGenericTypeMatch。)
- 检查是否有@Qualifier注解(org.springframework.beans.factory.support.AutowireCandidateResolver#hasQualifier)
- 推断是否含有@Primary注解(org.springframework.beans.factory.support.DefaultListableBeanFactory#determinePrimaryCandidate)
4、方法注入的方法
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) {
try {
arguments = resolveCachedArguments(beanName);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
arguments = resolveMethodArguments(method, bean, beanName);
}
}
else {
arguments = resolveMethodArguments(method, bean, beanName);
}
if (arguments != null) {
try {
ReflectionUtils.makeAccessible(method);
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
大致和属性方式注入相同,就不做具体描述。