Spring 依赖注入源码解析

接上一节内容,分析依赖注入和属性填充

贴上测试代码:

@Component
//@Order(2)
public class Test {
   public String test = "test";
}
@Component
public class UserService implements InitializingBean, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware, EmbeddedValueResolverAware , ApplicationContextAware {


	@Autowired
	private Test test;

	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("BeanNameAware.afterPropertiesSet()-------------");
	}

	public void test() {
		System.out.println("test");
	}

	@Override
	public void setBeanName(String name) {
		System.out.println("----BeanClassLoaderAware.setBeanClassLoader---");

	}

	@Override
	public void setBeanClassLoader(ClassLoader classLoader) {
		System.out.println("----BeanClassLoaderAware.setBeanClassLoader---");
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println("----BeanFactoryAware.setBeanFactory---");
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		System.out.println("----EnvironmentAware.setApplicationContext---");
	}

	@Override
	public void setEmbeddedValueResolver(StringValueResolver resolver) {
		System.out.println("----EmbeddedValueResolverAware.setEmbeddedValueResolver----");

	}

	@Override
	public void setEnvironment(Environment environment) {
		System.out.println("----ApplicationContextAware.setEnvironment----");

	}
}
public class Test {

	public static void main(String[] args) {

		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
//		TestBeanFactoryPostProcessor testBeanFactoryPostProcessor = new TestBeanFactoryPostProcessor();//要在实例化之前加入,还没找到怎么加入
//		applicationContext.addBeanFactoryPostProcessor(testBeanFactoryPostProcessor);
		UserService userService = applicationContext.getBean("userService", UserService.class);
		userService.test();

	}
}

我们的目的就是UserService中的

	@Autowired
	private Test test;

是什么时候注入的,是怎么注入的。

总之Spring在属性填充的时候,首先会去寻找注入点,然后根据注入点进行注入。

1.Spring 寻找注入点(@AutoWried @Resource @Value)

根据上一节的doCreateBean方法源码开始:

doCreateBean方法属性填充是在这一段

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					// 运行修改合并好了的BeanDefinition
					// 这里会查找@Autowired的注入点(InjectedElement),并把这些注入点添加到mbd的属性externallyManagedConfigMembers中
					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.
		// 如果当前创建的是单例bean,并且允许循环依赖,并且还在创建过程中,那么则提早暴露
		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");
			}
			// 此时的bean还没有完成属性注入,是一个非常简单的对象
			// 构造一个对象工厂添加到singletonFactories中
			// 第四次调用后置处理器
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));  // AService
		}

		// Initialize the bean instance.
		// 对象已经暴露出去了
		Object exposedObject = bean;
		try {
			// 3、填充属性 @Autowired
			populateBean(beanName, mbd, instanceWrapper);  //

			// 4、 初始化 和 BeanPostProcessor 正常AOP  BeanPostProcessor
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}

第一段代码非常重要

	synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					// 运行修改合并好了的BeanDefinition
					// 这里会查找@Autowired的注入点(InjectedElement),并把这些注入点添加到mbd的属性externallyManagedConfigMembers中
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}
	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}
		}
	}
MergedBeanDefinitionPostProcessor源码:
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {

	/**
	 * Post-process the given merged bean definition for the specified bean.
	 * @param beanDefinition the merged bean definition for the bean
	 * @param beanType the actual type of the managed bean instance
	 * @param beanName the name of the bean
	 * @see AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
	 */
	void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

	/**
	 * A notification that the bean definition for the specified name has been reset,
	 * and that this post-processor should clear any metadata for the affected bean.
	 * <p>The default implementation is empty.
	 * @param beanName the name of the bean
	 * @since 5.1
	 * @see DefaultListableBeanFactory#resetBeanDefinition
	 */
	default void resetBeanDefinition(String beanName) {
	}

}

这个接口也是继承BeanPostProcessor,所以也有该接口的功能。

这段代码其实非常简单,其实就是判断BeanFactory里面的beanPostProcessors是否有存在MergedBeanDefinitionPostProcessor类型的接口,然后调用MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)

现在我们来看这段代码都做了什么

利用debug模式打上条件断点

然后看一下BeanFactory里面的beanPostProcessors有几个后置处理器:

两个是自己加入的,其余的是Spring 启动的时候自己加入的(有几个特别熟悉有没有,在第一节我已经讲过了)

符合bp instanceof MergedBeanDefinitionPostProcessor 的有:

1.CommonAnnotationBeanPostProcessor

2.AutowiredAnnotationBeanPostProcessor

3.AnnotationConfigApplicationContext

再看这个几个类的postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)都做了什么:

1.CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName):

@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
		InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}

进入

super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		LifecycleMetadata metadata = findLifecycleMetadata(beanType);
		metadata.checkConfigMembers(beanDefinition);
	}
	private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
		if (this.lifecycleMetadataCache == null) {
			// Happens after deserialization, during destruction...
			return buildLifecycleMetadata(clazz);
		}
		// Quick check on the concurrent map first, with minimal locking.
		LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
		if (metadata == null) {
			synchronized (this.lifecycleMetadataCache) {
				metadata = this.lifecycleMetadataCache.get(clazz);
				if (metadata == null) {
					metadata = buildLifecycleMetadata(clazz);
					this.lifecycleMetadataCache.put(clazz, metadata);
				}
				return metadata;
			}
		}
		return metadata;
	}

由上可知这个方法就是查询父类的元数据信息LifecycleMetadata。

我们在来他是怎么拿出父类的信息的,进入metadata = buildLifecycleMetadata(clazz);

private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
		if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
			return this.emptyLifecycleMetadata;
		}

		List<LifecycleElement> initMethods = new ArrayList<>();
		List<LifecycleElement> destroyMethods = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {
			final List<LifecycleElement> currInitMethods = new ArrayList<>();
			final List<LifecycleElement> currDestroyMethods = new ArrayList<>();

			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
				if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
					LifecycleElement element = new LifecycleElement(method);
					currInitMethods.add(element);
					if (logger.isTraceEnabled()) {
						logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
					}
				}
				if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
					currDestroyMethods.add(new LifecycleElement(method));
					if (logger.isTraceEnabled()) {
						logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
					}
				}
			});

			initMethods.addAll(0, currInitMethods);
			destroyMethods.addAll(currDestroyMethods);
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class);

		return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
				new LifecycleMetadata(clazz, initMethods, destroyMethods));
	}

关键点:

targetClass = targetClass.getSuperclass();

while (targetClass != null && targetClass != Object.class);

其实就是一直循环取父类直到为null 和targetClass != Object.class(有空来测试继承的情况)

这里还有一个点就是:

AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType)
@Nullable
private Class<? extends Annotation> initAnnotationType;

@Nullable
private Class<? extends Annotation> destroyAnnotationType;

很直观的了解到,该方法还会去寻找初始方法和销毁方法存入到LifecycleMetadata,也就是标注@PostConstruct和@PreDestroy的方法。

继续往下面走:

InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
private InjectionMetadata findResourceMetadata(String beanName, final 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 = buildResourceMetadata(clazz);
					this.injectionMetadataCache.put(cacheKey, metadata);
				}
			}
		}
		return metadata;
	}

	private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
		if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
			return InjectionMetadata.EMPTY;
		}

		List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {
			final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

			ReflectionUtils.doWithLocalFields(targetClass, field -> {
				if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
					if (Modifier.isStatic(field.getModifiers())) {
						throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
					}
					currElements.add(new WebServiceRefElement(field, field, null));
				}
				else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) {
					if (Modifier.isStatic(field.getModifiers())) {
						throw new IllegalStateException("@EJB annotation is not supported on static fields");
					}
					currElements.add(new EjbRefElement(field, field, null));
				}
				else if (field.isAnnotationPresent(Resource.class)) {
					if (Modifier.isStatic(field.getModifiers())) {
						throw new IllegalStateException("@Resource annotation is not supported on static fields");
					}
					if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
						currElements.add(new ResourceElement(field, field, null));
					}
				}
			});

			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
				Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
				if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
					return;
				}
				if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
					if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
						if (Modifier.isStatic(method.getModifiers())) {
							throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
						}
						if (method.getParameterCount() != 1) {
							throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
						}
						PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
						currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
					}
					else if (ejbRefClass != null && bridgedMethod.isAnnotationPresent(ejbRefClass)) {
						if (Modifier.isStatic(method.getModifiers())) {
							throw new IllegalStateException("@EJB annotation is not supported on static methods");
						}
						if (method.getParameterCount() != 1) {
							throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
						}
						PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
						currElements.add(new EjbRefElement(method, bridgedMethod, pd));
					}
					else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
						if (Modifier.isStatic(method.getModifiers())) {
							throw new IllegalStateException("@Resource annotation is not supported on static methods");
						}
						Class<?>[] paramTypes = method.getParameterTypes();
						if (paramTypes.length != 1) {
							throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
						}
						if (!this.ignoredResourceTypes.contains(paramTypes[0].getName())) {
							PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
							currElements.add(new ResourceElement(method, bridgedMethod, pd));
						}
					}
				}
			});

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

		return InjectionMetadata.forElements(elements, clazz);
	}

也是循环去找父类的@Resource注入点(字段和方法)还有几个if else暂时不知道。

总而言之:

(1)该方法的主要作用是找出父类的LifecycleMetadata和标注@PostConstruct和@PreDestroy的方法注入点。

(2)找出字段和方法的@Resource注入点等一些操作。

2.AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName):

@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		// 获取beanType中的注入点
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}
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);
					}
					// 寻找当前clazz中的注入点,把所有注入点整合成为一个InjectionMetadata对象
					metadata = buildAutowiringMetadata(clazz);
					this.injectionMetadataCache.put(cacheKey, metadata);
				}
			}
		}
		return metadata;
	}

	private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {

		// 判断是不是候选者类,比如说类名,如果是以"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,@Inject注解
			ReflectionUtils.doWithLocalFields(targetClass, field -> {
				//
				MergedAnnotation<?> ann = findAutowiredAnnotation(field);
				// 如果存在@Autowired,@Value,@Inject注解其中一个
				if (ann != null) {
					// 如果字段是static的,则直接进行返回,不进行注入
					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);
					// 生成一个注入点AutowiredFieldElement
					currElements.add(new AutowiredFieldElement(field, required));
				}
			});

			// 遍历方法,看是否有@Autowired,@Value,@Inject注解
			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;
					}
					// 方法参数值为0,不能用来注入属性
					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);
	}

其实从

InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata = buildAutowiringMetadata(clazz);

就可以看出就是在找@Autowire的注入点,但是值得注意得是还在找@Value的注入点(方法和字段,方法参数为0的时候不用来注入),当然也是循环也找父类的注入点。关键代码如下:

AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes

MergedAnnotation<?> ann = findAutowiredAnnotation(field);
targetClass = targetClass.getSuperclass();
while (targetClass != null && targetClass != Object.class);

总而言之:该方法是寻找当前类及父类标注@Autowire和@Value的注入点(字段和方法)

3.AnnotationConfigApplicationContext.postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName):

	// 实例化之后,填充属性之前会执行,会把某个ApplicationListener的bean的名字添加到singletonNames中去
	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		if (ApplicationListener.class.isAssignableFrom(beanType)) {
			this.singletonNames.put(beanName, beanDefinition.isSingleton());
		}
	}

这个方法就不做过多解释了。

2.上面已经找到注入点了,下面我们来分析怎么注入的

直接F8跳到:

	// 3、填充属性 @Autowired
			populateBean(beanName, mbd, instanceWrapper);  

进入该方法,该方法里面有一段:

for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

					// 调用BeanPostProcessor分别解析@Autowired、@Resource、@Value,得到属性值
					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;
				}
			}
		}

有没有非常熟悉,其实主要的目的是遍历BeanFactory里面的BeanPostProcessors,然后判断

bp instanceof InstantiationAwareBeanPostProcessor

调用InstantiationAwareBeanPostProcessor.postProcessProperties方法,我们在看各个InstantiationAwareBeanPostProcessor都做了什么

1.CommonAnnotationBeanPostProcessor.postProcessProperties:

@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
		InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
		try {
			metadata.inject(bean, beanName, pvs);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
		}
		return pvs;
	}

很直观的了解到,这是对父类的属性注入,还解析@Resource注入点注入:

@Override
		protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
			return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
					getResource(this, requestingBeanName));
		}
protected Object getResource(LookupElement element, @Nullable String requestingBeanName)
			throws NoSuchBeanDefinitionException {

		if (StringUtils.hasLength(element.mappedName)) {
			return this.jndiFactory.getBean(element.mappedName, element.lookupType);
		}
		if (this.alwaysUseJndiLookup) {
			return this.jndiFactory.getBean(element.name, element.lookupType);
		}
		if (this.resourceFactory == null) {
			throw new NoSuchBeanDefinitionException(element.lookupType,
					"No resource factory configured - specify the 'resourceFactory' property");
		}
		return autowireResource(this.resourceFactory, element, requestingBeanName);
	}
	protected Object autowireResource(BeanFactory factory, LookupElement element, @Nullable String requestingBeanName)
			throws NoSuchBeanDefinitionException {

		Object resource;
		Set<String> autowiredBeanNames;
		String name = element.name;

		if (factory instanceof AutowireCapableBeanFactory) {
			AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
			DependencyDescriptor descriptor = element.getDependencyDescriptor();
			if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
				autowiredBeanNames = new LinkedHashSet<>();
				resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
				if (resource == null) {
					throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
				}
			}
			else {
				resource = beanFactory.resolveBeanByName(name, descriptor);
				autowiredBeanNames = Collections.singleton(name);
			}
		}
		else {
			resource = factory.getBean(name, element.lookupType);
			autowiredBeanNames = Collections.singleton(name);
		}

		if (factory instanceof ConfigurableBeanFactory) {
			ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;
			for (String autowiredBeanName : autowiredBeanNames) {
				if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) {
					beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);
				}
			}
		}

		return resource;
	}

继续往下面走:

2.AutowiredAnnotationBeanPostProcessor.postProcessProperties

@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
		// InjectionMetadata中保存了所有被@Autowired注解标注的属性/方法并封装成一个个的InjectedElement
		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;
	}
// InjectionMetadata中保存了所有被@Autowired注解标注的属性/方法并封装成一个个的InjectedElement
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);

这些注入点从哪里来,不就是从上面合并出来的嘛

再次进入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可能是Method,也可能是Field
				element.inject(target, beanName, pvs);
			}
		}
	}
@Override
		protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
			Field field = (Field) this.member;
			Object value;
			if (this.cached) {
				// 当前注入点已经注入过了,有缓存了,则利用cachedFieldValue去找对应的bean
				value = resolvedCachedArgument(beanName, this.cachedFieldValue);
			}
			else {
				//  Spring在真正查找属性对应的对象之前, 会先将该属性的描述封装成一个DependencyDescriptor, 里面保存了Filed、是否强制需要即required, 以及属性所在的类(即Field所在的类Class对象)
				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 {
					// 根据field去寻找合适的bean
					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;
							// 注册当前bean依赖了哪些其他的bean的name
							registerDependentBeans(beanName, autowiredBeanNames);
							if (autowiredBeanNames.size() == 1) {
								String autowiredBeanName = autowiredBeanNames.iterator().next();
								if (beanFactory.containsBean(autowiredBeanName) &&
										beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
									// 对得到的对象进行缓存
									this.cachedFieldValue = new ShortcutDependencyDescriptor(
											desc, autowiredBeanName, field.getType());
								}
							}
						}
						else {
							this.cachedFieldValue = null;
						}
						this.cached = true;
					}
				}
			}
			// 反射设值
			if (value != null) {
				ReflectionUtils.makeAccessible(field);
				field.set(bean, value);
			}
		}
	}

这个方法就是确定一个唯一的注入点确定值,有可能找到的是类,则需要

beanFactory.getBean(beanName);创建bean对象

然后通过反射的方式设置进去

这里面存在一个问题就是,如何确定一个唯一的值,其实在DefaultListableBeanFactory工厂里面有一个protected String determineAutowireCandidate(Map candidates, DependencyDescriptor descriptor)方法:

@Nullable
	protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
		Class<?> requiredType = descriptor.getDependencyType();

		// 取@Primary的bean
		String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
		if (primaryCandidate != null) {
			return primaryCandidate;
		}

		// 取优先级最高的bean 通过@Priority来定义优先级,数字越小,优先级越高
		String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
		if (priorityCandidate != null) {
			return priorityCandidate;
		}

		// Fallback
		for (Map.Entry<String, Object> entry : candidates.entrySet()) {
			String candidateName = entry.getKey();
			Object beanInstance = entry.getValue();
			if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
					// 根据属性名确定
					matchesBeanName(candidateName, descriptor.getDependencyName())) {
				return candidateName;
			}
		}
		return null;
	}

里面有注释可以自行观看

其实该方法就是先去根据@Primary的bean确定唯一值,然后取优先级最高的bean 通过@Priority来定义优先级,数字越小,优先级越高,最后根据属性名来确定。

3.对于自己重写的InstantiationAwareBeanPostProcessor.postProcessProperties造成什么样的结果后续分析

总结:

1.通过内置的MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition方法寻找注入点

2.然后过内置InstantiationAwareBeanPostProcessor.postProcessProperties的方法进行属性注入。

补充一个知识点:

父子BeanDefinition

父子BeanDefinition是Spring中的概念,Spring在根据BeanDefinition创建Bean的过程中,会先看当前BeanDefinition是否存在父BeanDefinition,如果存在则需要进行合并,合并就是把子BeanDefinition和父BeanDefinition中所定义的属性整合起来(如果存在某个属性在父子BeanDefinition中都存在,那么取子BeanDefinition中的属性)

网上找到的一个例子:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="parent" abstract="true"
          class="com.dmz.official.merge.TestBean">
        <property name="name" value="parent"/>
        <property name="age" value="1"/>
    </bean>
    <bean id="child"
          class="com.dmz.official.merge.DerivedTestBean"
          parent="parent" >
        <property name="name" value="override"/>
    </bean>
</beans>
public class DerivedTestBean {
    private String name;

    private int age;

    // 省略getter setter方法
}

public class TestBean {
    private String name;

    private String age;

     // 省略getter setter方法
}

public class Main {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext cc = new ClassPathXmlApplicationContext("application.xml");
        DerivedTestBean derivedTestBean = (DerivedTestBean) cc.getBean("child");
        System.out.println("derivedTestBean的name = " + derivedTestBean.getName());
        System.out.println("derivedTestBean的age = " + derivedTestBean.getAge());
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值