Spring源码之依赖注入、初始化分析

文章目录

  • 前言
  • 一、注解的装配收集
  • 二、属性的依赖注入
  • 三、bean实例化后置处理
    • 3.1.调用Aware方法
    • 3.2.对类中某些特殊方法的调用,比如@PostConstruct
    • 3.3.调用InitMethod方法
    • 3.4.调用postProcessAfterInitialization方法
  • 总结


前言

  上篇文章讲过了Spring实例化bean调用类的构造方法,但只是在堆内存中分配一块内存空间,但是类中的属性还没有注入到对象中,这篇文章着重讲解依赖注入的过程……


一、注解的装配收集

// 这个方法主要完成对类中注解的收集工作
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
     
		// 循环遍历所有的BeanPostProcessor
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
     
		//调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
     
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
				//收集到所有的注解信息封装到InjectionMetadata中
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}
		}
	}

循环遍历所有的MergedBeanDefinitionPostProcessor,主要有以下几种用于对注解的收集:

  1. AutowiredAnnotationBeanPostProcessor:处理@Autowired、@Value注解的收集
  2. CommonAnnotationBeanPostProcessor:处理@Resource注解的收集
  3. InitDestroyAnnotationBeanPostProcessor:处理@PostConstruct、@PreDestroy注解的收集

我们以AutowiredAnnotationBeanPostProcessor为例具体看看是怎么进行注解的收集工作的?

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) {
     
	// 缓存key值
	String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
	// 首先检查injectionMetadataCache缓存中是否有值,有则直接返回
	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;
}

接下里我们看,注解信息的主要封装过程buildAutowiringMetadata方法

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
     
	// 如果类中没有相关注解,则返回空
	if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
     
		return InjectionMetadata.EMPTY;
	}
	// InjectedElement类型的集合
	List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
	Class<?> targetClass = clazz;

	do {
     
		final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
		// 寻找field上面的@Autowire注解并封装成对象
		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);
				// 将属性方面的的注解封装成AutowiredFieldElement放到currElements集合中
				// AutowiredFieldElement为InjectedElement的子类
				currElements.add(new AutowiredFieldElement(field, required));
			}
		});

		// 寻找method上面的@Autowire注解并封装成对象
		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);
				//封装成AutowiredMethodElement放到currElements集合中
				// AutowiredMethodElement是InjectedElement的子类
				currElements.add(new AutowiredMethodElement(method, required, pd));
			}
		});
		//final修饰的currElements中的值放到elements中
		elements.addAll(0, currElements);
		targetClass = targetClass.getSuperclass();
	}
	while (targetClass != null && targetClass != Object.class);
	//封装成InjectionMetadata
	return InjectionMetadata.forElements(elements, clazz);
}

我们在对属性进行依赖注入的时候,推荐使用@Resource注解,因为@Resource注解是JDK支持的,那么我们来看看Spring对@Resource的处理

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
     
	super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
	// 处理@Resource注解的收集
	InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
	metadata.checkConfigMembers(beanDefinition);
}

经过跟踪源码,整体流程和对@Autowired的处理大同小异,但不同的是调用了父类的
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName)
这里又是做了些什么呢?

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
     
	// 处理@PostConstruct、@PreDestroy注解的收集
	LifecycleMetadata metadata = findLifecycleMetadata(beanType);
	metadata.checkConfigMembers(beanDefinition);
}

继续看findLifecycleMetadata

private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
     
	if (this.lifecycleMetadataCache == null) {
     
		// Happens after deserialization, during destruction...
		return buildLifecycleMetadata(clazz);
	}
	// 缓存中获取
	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;
}

接着来看buildLifecycleMetadata方法

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 -> {
     
			//initAnnotationType是@PostConstruct注解
			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);
				}
			}
			// destroyAnnotationType是@preDestroy注解
			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));
}

二、属性的依赖注入

applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
|
>这个名字起的就非常有意思,填充bean,
populateBean(beanName, mbd, instanceWrapper);

看看这个方法的具体操作

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
     
	// 对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;
		}
	}

	//在设置属性之前,让任何InstantiationAwareBeanPostProcessors都有机会修改Bean的状态。
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
     
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
     
			//实现InstantiationAwareBeanPostProcessor接口
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
     
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				// 是否需要DI
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
     
					return;
				}
			}
		}
	}
	//postProcessPropertyValues是属于弃用状态,暂不关注
	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;
				// @Autowire支持依赖注入的过程,主要看这里
				PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
     
					if (filteredPds == null) {
     
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}

					// 老版本用这个完成依赖注入的过程,@Autowire的支持
					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);
	}

	// 标签做依赖注入的代码实现,复杂且无用
	if (pvs != null) {
     
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
}

进入postProcessProperties方法,这个方法是一个钩子方法,直接看实现类
AutowiredAnnotationBeanPostProcessor.postProcessProperties

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
     
	//这个方法是不是很熟悉呢,在注解收集的时候调用过,所以这里直接从缓存中拿到InjectionMetadata
	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;
}

进入到metadata.inject(bean, beanName, pvs);

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

进入到子类AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement的inject方法

/**
 * inject 依赖注入的最终反射实现
 */
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 {
     
		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 = 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;
					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的依赖注入通过反射实现
		field.set(bean, value);
	}
}

方法的依赖注入与字段的类似,调用的子类AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement的inject方法,这里不多做赘述。

三、bean实例化后置处理

bean实例化并且IOC依赖注入完成之后,调用

exposedObject = initializeBean(beanName, exposedObject, mbd);

该方法都做了哪些事情呢

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
     
	if (System.getSecurityManager() != null) {
     
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
     
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	}
	else {
     
		// 1.调用Aware方法
		invokeAwareMethods(beanName, bean);
	}

	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
     
		// 2.对类中某些特殊方法的调用,比如@PostConstruct、Aware接口
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	try {
     
		// 3.调用InitMethod方法
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
     
		throw new BeanCreationException(
				(mbd != null ? mbd.getResourceDescription() : null),
				beanName, "Invocation of init method failed", ex);
	}
	if (mbd == null || !mbd.isSynthetic()) {
     
		// 4.调用BeanPostProcessor的postProcessAfterInitialization方法
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}

下面分别从方法中注释的4点进行分析

3.1.调用Aware方法

进入方法中

private void invokeAwareMethods(String beanName, Object bean) {
     
	if (bean instanceof Aware) {
     
		if (bean instanceof BeanNameAware) {
     
			((BeanNameAware) bean).setBeanName(beanName);
		}
		if (bean instanceof BeanClassLoaderAware) {
     
			ClassLoader bcl = getBeanClassLoader();
			if (bcl != null) {
     
				((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
			}
		}
		if (bean instanceof BeanFactoryAware) {
     
			((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
		}
	}
}

Aware是一个接口,官方的解释是一个超级标记接口,用于指示bean有资格通过回调样式方法由Spring容器通知特定框架对象,实际的方法签名由各个子接口确定。所以如果实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware,则会调用相应的方法。

3.2.对类中某些特殊方法的调用,比如@PostConstruct

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
		throws BeansException {
     

	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
     
		Object current = processor.postProcessBeforeInitialization(result, beanName);
		if (current == null) {
     
			return result;
		}
		result = current;
	}
	return result;
}

这里以InitDestroyAnnotationBeanPostProcessor为例

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
     
	//这个方法上面也见过了,收集@PostConstruct和@PreDestroy注解
	LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
	try {
     
		//利用反射进行方法调用
		metadata.invokeInitMethods(bean, beanName);
	}
	catch (InvocationTargetException ex) {
     
		throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
	}
	catch (Throwable ex) {
     
		throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
	}
	return bean;
}

3.3.调用InitMethod方法

指定初始化方法

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
		throws Throwable {
     
	// 如果当前 bean 是 InitializingBean 的实例
	boolean isInitializingBean = (bean instanceof InitializingBean);
	if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
     
		if (logger.isTraceEnabled()) {
     
			logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
		}
		if (System.getSecurityManager() != null) {
     
			try {
     
				AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
     
					((InitializingBean) bean).afterPropertiesSet();
					return null;
				}, getAccessControlContext());
			}
			catch (PrivilegedActionException pae) {
     
				throw pae.getException();
			}
		}
		else {
     
			// 直接调用afterPropertiesSet方法
			((InitializingBean) bean).afterPropertiesSet();
		}
	}

	if (mbd != null && bean.getClass() != NullBean.class) {
     
		String initMethodName = mbd.getInitMethodName();
		if (StringUtils.hasLength(initMethodName) &&
				!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
				!mbd.isExternallyManagedInitMethod(initMethodName)) {
     
			// 调用init-method配置的方法
			invokeCustomInitMethod(beanName, bean, mbd);
		}
	}
}

3.4.调用postProcessAfterInitialization方法

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {
     

	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
     
		Object current = processor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
     
			return result;
		}
		result = current;
	}
	return result;
}

初始化之后对bean的处理,这里以ApplicationListenerDetector为例,这里可以做为事件监听bean的探测器,将监听bean放到上下文的监听器集合中。

public Object postProcessAfterInitialization(Object bean, String beanName) {
     
	if (bean instanceof ApplicationListener) {
     
		// potentially not detected as a listener by getBeanNamesForType retrieval
		Boolean flag = this.singletonNames.get(beanName);
		if (Boolean.TRUE.equals(flag)) {
     
			// 事件监听的收集
			this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
		}
		else if (Boolean.FALSE.equals(flag)) {
     
			if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
     
				// inner bean with other scope - can't reliably process events
				logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
						"but is not reachable for event multicasting by its containing ApplicationContext " +
						"because it does not have singleton scope. Only top-level listener beans are allowed " +
						"to be of non-singleton scope.");
			}
			this.singletonNames.remove(beanName);
		}
	}
	return bean;
}

总结

  • 调用applyMergedBeanDefinitionPostProcessor和populateBean完成DI
  • 调用初始化方法的前后,会调用BeanPostProcessor的applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization方法对bean进行处理,我们可以依托于此对Spring进行二次开发。

你可能感兴趣的:(Spring源码,spring,源码,ioc,bean,java)