Spring @Autowired注解的调用栈

先来一张图:

Spring @Autowired注解的调用栈_第1张图片

大致流程是:容器刷新时,调用refresh()方法,然后在运行到finishBeanFactoryInitialization()的时候,会调用到preInstantiateSingletons()去获取Bean。getBean()方法获取Bean时,首先看看缓存有没有,如果没有就会调用创建Bean的流程。创建Bean的流程里,在populateBean()之前,applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);方法会调用AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()方法把被@Autowired标注的属性放到AutowiredAnnotationBeanPostProcessor的this.injectionMetadataCache缓存里,即上图第一行代码所做工作。

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

在populateBean()的时候(如下图),会调用AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues()进而调用findAutowiringMetadata直接从上面构建的缓存中取出InjectionMetadata,然后执行注入(inject)流程。

 

 

经过一系列的处理后会再次调用getBean()方法去获取(创建)需要被自动注入的那个Bean。

Spring @Autowired注解的调用栈_第2张图片

总结一下AutowiredAnnotationBeanPostProcessor这个Bean后置处理器中比较重要的内容:

1. this.injectionMetadataCache属性

这个缓存中保存了一个Bean是否包含需要自动注入其他Bean的信息。如果某个key(key为Bean的名字)的value值InjectionMetadata的injectedElements链表长度大于1,表明这个Bean需要注入其他Bean。

2. postProcessMergedBeanDefinition()方法。

这个方法会在Bean创建的时候,在doCreateBean()方法中被调用到。具体的调用时机是:在createBeanInstance()之后,populateBean()之前。postProcessMergedBeanDefinition()方法的主要功能是检查Bean是否需要注入其他Bean,构建好injectionMetadataCache缓存。

3. postProcessPropertyValues()方法

这个方法的调用时机是在populateBean()方法里面。主要功能是从injectionMetadataCache缓存中拿到需要注入的其他Bean信息,执行注入流程。而注入流程进而会调到getBean()方法,进行递归。。。

整个流程:

getBean()->doGetBean()->getSingleton()->getObject()->lambda$doGetBean()->createBean()->doCreateBean()

doCreateBean()

|----createBeanInstance()

|----applyMergedBeanDefinitionPostProcessors()->postProcessMergedBeanDefinition()->findAutowiringMetadata() //构建injectionMetadataCache缓存
|
|----populateBean()
     |
     |----postProcessAfterInstantiation()
     |
     |----postProcessPropertyValues()->AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues()
                                     |
                                     |---1. findAutowiringMetadata()//读injectionMetadataCache缓存 
                                     |
                                     |---2. metadata.inject(bean, beanName, pvs);//执行注入流程,注入流程经过几步之后再会执行到getBean()

metadata.inject(bean,beanName,pvs)

-> InjectionMetadata.InjectedElement.inject(target, beanName, pvs);

->AutowiredAnnotationBeanPostProcessor.inject()

->DefaultListableBeanFactory.resolveDependency()

->DefaultListableBeanFactory.doResolveDependency()

->DefaultListableBeanFactory.findAutowireCandidates()

->DefaultListableBeanFactory.addCandidateEntry()

->DependencyDescriptor.resolveCandidate()

->return beanFactory.getBean(beanName);

           

 

你可能感兴趣的:(J2EE)