Spring @Autowird注解和@Resouce注解源码分析

从使用上来看@Autowird和@Resource注解的区别

  • 两个注解都可用于属性或者方法上的注入;@Autowired是默认按照类型装配, @Resource默认是按照名称装配

从提供来源看:

  • @Autowired是由Spring提供
  • @Resource是有java提供,在包javax.annotation下

从spring处理源看:

  • @Autowired是由AutowiredAnnotationBeanPostProcessor后处理器进行处理
  • @Resource是由CommonAnnotationBeanPostProcessor后处理器进行处理

它们在spring bean生命周期中扮演依赖注入的角色,从bean的生命周期来看,有两处使用后处理器进行处理,分别发生在

  • bean实例化之后 属性填充方法populateBean调用之前,通过applyMergedBeanDefinitionPostProcessors方法,
    将bean中通过@Autowire,@Resource等注解的属性 解析封装在InjectionMetadata结构中 并缓存起来,供下一步直接取用
  • AbstractAutowireCapableBeanFactory#populateBean中,在实例化后的后处理器调用之后,
    通过postProcessProperties方法将InjectionMetadata数据解析,然后注入到bean实例中

为方便描述,上述生命周期中两个调用阶段分别简称为一阶段,二阶段

接下来从源码上来看看~

源码分析

spring bean生命周期之创建bean实例 doCreateBean,这里是可以找到对@Autowired和@Resource处理的入口

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
		throws BeanCreationException {

	// Instantiate the bean.
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		// todo
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = instanceWrapper.getWrappedInstance();
	Class beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}

	// Allow post-processors to modify the merged bean definition.
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
			    // 这里便是入口了,会使用不同的后处理器尝试处理带注解的属性
			    // 并封装成在InjectionMetadata数据
			    // 也就是上面说的第一阶段
				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.
	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");
		}
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}

	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
	    // 填充属性
		populateBean(beanName, mbd, instanceWrapper);
		// bean初始化
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
	catch (Throwable ex) {
		if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
			throw (BeanCreationException) ex;
		}
		else {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
		}
	}
	
    .......
}    

// 填充属性
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	if (bw == null) {
		if (mbd.hasPropertyValues()) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
		}
		else {
			// Skip property population phase for null instance.
			return;
		}
	}

	// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
	// state of the bean before properties are set. This can be used, for example,
	// to support styles of field injection.
	// 实例化后的后处理操作
	// 给InstantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				// 返回值为是否继续填充bean
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}
	}

	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

	int resolvedAutowireMode = mbd.getResolvedAutowireMode();
	if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
		// Add property values based on autowire by name if applicable.
		// 根据名称自动注入
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}
		// Add property values based on autowire by type if applicable.
		// 根据类型自动注入
		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;
				// 对所有需要依赖检查的属性进行后处理
				// 这里便是第二步处理,从缓存中拿到InjectionMetadata,并解析,通过依赖注入的方式给属性赋值
				// 也就是上面说的第二阶段
				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;
			}
		}
	}
	if (needsDepCheck) {
		if (filteredPds == null) {
			filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		}
		checkDependencies(beanName, mbd, filteredPds, pvs);
	}

	// 将属性应用到bean中
	if (pvs != null) {
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
}   	

好了,上面是找到对注解处理的入口,下面开始分析对注解处理的源码…

来看看主要对注解处理的三个后处理器的分工

  • AutowiredAnnotationBeanPostProcessor,主要是针对spring的注解
  • InitDestroyAnnotationBeanPostProcessor,主要是java注解 初始化、销毁等;通常在子类CommonAnnotationBeanPostProcessor中就可完成其功能
  • CommonAnnotationBeanPostProcessor,主要是针对java注解

AutowiredAnnotationBeanPostProcessor

一阶段:

AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition方法

// 前一阶段, 而 postProcessProperties 在后一阶段
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) {
	// 找到相关的注解,并封装成InjectionMetadata结构
	InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
	metadata.checkConfigMembers(beanDefinition);
}

findAutowiringMetadata方法,构建依赖注入元数据信息并缓存起来

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);
				}
				// 这里便开始构建AutowiringMetadata数据
				metadata = buildAutowiringMetadata(clazz);
				this.injectionMetadataCache.put(cacheKey, metadata);
			}
		}
	}
	return metadata;
}   

buildAutowiringMetadata方法,这里才是真正的使用反射构建InjectionMetadata数据
代码上很简单,通过反射工具ReflectionUtils找到对应的带注解的属性

// 构建Autowiring元信息
private InjectionMetadata buildAutowiringMetadata(final Class clazz) {
	if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
		return InjectionMetadata.EMPTY;
	}

	List elements = new ArrayList<>();
	Class targetClass = clazz;

	do {
		final List 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;
				}
				boolean required = determineRequiredStatus(ann);
				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);
			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);
					}
				}
				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);
}

@Nullable
private MergedAnnotation findAutowiredAnnotation(AccessibleObject ao) {
	MergedAnnotations annotations = MergedAnnotations.from(ao);
	for (Class type : this.autowiredAnnotationTypes) {
		MergedAnnotation annotation = annotations.get(type);
		// 说明有按顺序优先处理
		if (annotation.isPresent()) {
			return annotation;
		}
	}
	return null;
}	

二阶段

AutowiredAnnotationBeanPostProcessor#postProcessProperties

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
	// findResourceMetadata这里也是一阶段会调用的方法,和一阶段不同的是这里直接从缓存中取出来
	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;
}

可以看到,二阶段主要针对InjectionMetadata数据进行依赖注入,依赖注入的过程也很是繁琐…

来看看AutowiredAnnotationBeanPostProcessor的构造方法,有明确显示可处理的注解:

/**
 * Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's
 * standard {@link Autowired @Autowired} and {@link Value @Value} annotations.
 * 

Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation, * if available. */ @SuppressWarnings("unchecked") public AutowiredAnnotationBeanPostProcessor() { this.autowiredAnnotationTypes.add(Autowired.class); this.autowiredAnnotationTypes.add(Value.class); try { // 可以看到这里也提供对jsr-330的@Inject注解的支持,此注解和@Autowire类似 this.autowiredAnnotationTypes.add((Class) 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. } }

总结一下,一阶段通过反射的方式找到相关的注解封装成InjectionMetadata结构,并缓存起来;在第二阶段直接从缓存中拿到InjectionMetadata数据,然后开始执行依赖注入过程…

CommonAnnotationBeanPostProcessor

和AutowiredAnnotationBeanPostProcessor结构上和功能上基本一致,大致看看代码实现

一阶段

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) {
	// 注意: 这里比AutowiredAnnotationBeanPostProcessor多了一个生命周期处理
	// 也就是父类InitDestroyAnnotationBeanPostProcessor的方法对bean生命周期中@PostConstruct,@PreDestroy的支持
	super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
	
	// 仍然是封装返回InjectionMetadata数据
	InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
	metadata.checkConfigMembers(beanDefinition);
}

// 看看这里是不很相似
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);
				}
				// 构建InjectionMetadata数据
				metadata = buildResourceMetadata(clazz);
				this.injectionMetadataCache.put(cacheKey, metadata);
			}
		}
	}
	return metadata;
}

来看看super.postProcessMergedBeanDefinition,也就是父类的第一阶段,不同的是构建的数据是LifecycleMetadata,针对bean生命周期处理的元数据信息
但是在实现方式上却是异曲同工~

// InitDestroyAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) {
	LifecycleMetadata metadata = findLifecycleMetadata(beanType);
	// 这一步是对RootBeanDefinition生命周期方法的注入,比如init,destroy
	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;
}

// 构建元信息
private LifecycleMetadata buildLifecycleMetadata(final Class clazz) {
	if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
		return this.emptyLifecycleMetadata;
	}

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

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

		// 通过查找所有类型找到用于Destroy的method
		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));
}

可以看到,在CommonAnnotationBeanPostProcessor中,通过调用super.postProcessMergedBeanDefinition对父类InitDestroyAnnotationBeanPostProcessor
的Metadata元数据的解析构建,只不过构建的LifecycleMetadata数据是对spring bean生命周期的管理

buildResourceMetadata通过反射构建数据,取出通过@Resource注解的属性

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

	List elements = new ArrayList<>();
	Class targetClass = clazz;

	do {
		final List 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);
	
	
}	

来看看CommonAnnotationBeanPostProcessor支持哪些注解

首先是构造函数,对@PostConstruct,@PreDestroy的支持

/**
 * Create a new CommonAnnotationBeanPostProcessor,
 * with the init and destroy annotation types set to
 * {@link javax.annotation.PostConstruct} and {@link javax.annotation.PreDestroy},
 * respectively.
 */
public CommonAnnotationBeanPostProcessor() {
	setOrder(Ordered.LOWEST_PRECEDENCE - 3);
	setInitAnnotationType(PostConstruct.class);
	// 销毁类型
	setDestroyAnnotationType(PreDestroy.class);
	ignoreResourceType("javax.xml.ws.WebServiceContext");
}

再看看静态代码段,对@Resource注解的支持

static {
	try {
		@SuppressWarnings("unchecked")
		Class clazz = (Class)
				ClassUtils.forName("javax.xml.ws.WebServiceRef", CommonAnnotationBeanPostProcessor.class.getClassLoader());
		webServiceRefClass = clazz;
	}
	catch (ClassNotFoundException ex) {
		webServiceRefClass = null;
	}

	try {
		@SuppressWarnings("unchecked")
		Class clazz = (Class)
				ClassUtils.forName("javax.ejb.EJB", CommonAnnotationBeanPostProcessor.class.getClassLoader());
		ejbRefClass = clazz;
	}
	catch (ClassNotFoundException ex) {
		ejbRefClass = null;
	}

    // 这里表明了对@Resource注解的支持
	resourceAnnotationTypes.add(Resource.class);
	if (webServiceRefClass != null) {
		resourceAnnotationTypes.add(webServiceRefClass);
	}
	if (ejbRefClass != null) {
		resourceAnnotationTypes.add(ejbRefClass);
	}
}

小结

上述一阶段和二阶段对注解的处理处于bean生命周期的实例化之后,初始化之前,这个过程通过反射找到相关注解的属性,然后通过依赖注入的方式给属性赋值

以上是个人理解,如果问题指出,谢谢!

你可能感兴趣的:(Spring系列)