Spring源码分析之Bean的属性填充以及初始化

前言

  在Spring源码分析之Bean的实例化(createBeanInstance())-优快云博客我们已经说了怎么实例化Bean对象,但是实例化这一步骤的话其实这个仅仅只是说整个生命周期的第一步(Bean的实例化)那么后面的话我们就是会说完这个Bean的生命周期也就是说是属性填充以及初始化,这个相对于实例化而言就是简单的多了

populateBean():

   这个就是说进行属性填充主要就是应用于doCreateBean创建的对象

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;
			}
		}
        //如果是不可变的但是有属性值进行赋值
		if (bw.getWrappedClass().isRecord()) {
			if (mbd.hasPropertyValues()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to a record");
			}
			else {
				// Skip property population phase for records since they are immutable.
				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.
		//如果RootDefinition实现了hasInstantiationAwareBeanPostProcessors()接口
		//这个接口的话就是在对象实例化之后进行一些额外的操作
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
        //这个就是说进行获得这个RootBeanDefinition的自动装配的模式进行属性填充
		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;
		}
		//是否实现hasInstantiationAwareBeanPostProcessors()
		 //可以进行属性的修改
		if (hasInstantiationAwareBeanPostProcessors()) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					return;
				}
				pvs = pvsToUse;
			}
		}
       //如果启用了依赖检查,则执行依赖检查
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
		if (needsDepCheck) {
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}
      //最终完成
		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

1.进行属性填充的判断:

//如果RootDefinition实现了hasInstantiationAwareBeanPostProcessors()接口
		//这个接口的话就是在对象实例化之后进行一些额外的操作
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
                //如果没有实现这个postProcessAfterInstantiation方法那么就是直接进行跳过
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}
InstantiationAwareBeanPostProcessors():

这个就是说是一个实例化回调接口进行一些额外业务逻辑的处理: 在实例化之前我们可以用其在实例化之前进行一些业务的修改使得我们创建的对象是代理对象  实例化之后就会调用这个里面的方法的话那么这个时候就会修改里面的属性

//这个方法就是说如果要进行创建代理对象的话那么就要调用这个接口
//这个就是说在没有实例化之前就会进行额外的操作
@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}
//这个方法就是说在Bean实例化之后但是没有属性注入之前那么这个时候
//调用这个方法那么我们可以添加一些额外的属性如:判断创建的对象的状态
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}
//修改目标属性的值
@Nullable
	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
			throws BeansException {

		return pvs;
	}

2.进行自动装配:

其实这个就是很简单的就是根据Type还是说根据Name进行依赖注入

2.1根据名字进行依赖注入:这个就是不断进行递归找到目标的Bean(通过getBean)

	protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
		// 寻找bw中需要依赖注入的属性name
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			// 检查是否有这个bean对象
			if (containsBean(propertyName)) {
				// 递归初始化bean,会调用doGetBean 来 获取bean
				Object bean = getBean(propertyName);
				pvs.add(propertyName, bean);
				// 注册依赖,将依赖关系保存到 Map<String, Set<String>> dependentBeanMapdependentBeanMap 中,key是 bean,value是 转化后的 propertyName
				registerDependentBean(propertyName, beanName);
				if (logger.isTraceEnabled()) {
					logger.trace("Added autowiring by name from bean name '" + beanName +
							"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
							"' by name: no matching bean found");
				}
			}
		}
	}

2.2根据类型进行依赖注入:

protected void autowireByType(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
		//获得类型转换器
		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
        //这个就是找到需要的Name
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		Set<String> autowiredBeanNames = new LinkedHashSet<>(propertyNames.length * 2);
		for (String propertyName : propertyNames) {
			try {
				//获得属性描述符
				PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
				// Don't try autowiring by type for type Object: never makes sense,
				// even if it technically is an unsatisfied, non-simple property.
				if (Object.class != pd.getPropertyType()) {
					//获得这个属性的set方法
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
					// Do not allow eager init for type matching in case of a prioritized post-processor.
					boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
					//在工厂中找到符合条件的Bean对象
					Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
					if (autowiredArgument != null) {
						pvs.add(propertyName, autowiredArgument);
					}
					for (String autowiredBeanName : autowiredBeanNames) {
						// 注册依赖关系
						//主要就是通过dependentBeanMap 和  dependenciesForBeanMap 集合进行完成
						registerDependentBean(autowiredBeanName, beanName);
						if (logger.isTraceEnabled()) {
							logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
									propertyName + "' to bean named '" + autowiredBeanName + "'");
						}
					}
					autowiredBeanNames.clear();
				}
			}
			catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
			}
		}
	}

3.成员变量的注入:

  Spring 默认是通过 AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues 的实现来完成的属性的注入但是这个里面进行查看的话其实根本上就是通过inject实现赋值但是根本的操作其实就是反射而已

inject():
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
		throws Throwable {

	// 检查是否需要进行注入
	if (!shouldInject(pvs)) {
		return;
	}

	// 判断是注入到字段还是方法
	if (this.isField) {
		Field field = (Field) this.member;
		ReflectionUtils.makeAccessible(field);  // 使字段可访问
		field.set(target, getResourceToInject(target, requestingBeanName));  // 注入依赖项
	}
	else {
		try {
			Method method = (Method) this.member;
			ReflectionUtils.makeAccessible(method);  // 使方法可访问
			method.invoke(target, getResourceToInject(target, requestingBeanName));  // 调用方法并注入依赖项
		}
		catch (InvocationTargetException ex) {
			throw ex.getTargetException();  // 抛出嵌套的目标异常
		}
	}
}

4.applyPropertyValues:

  上面的方法最重要的就是只是将数据进行保存但是没有真实地应用到对象实例当中如:postProcessPropertyValues这个方法就是通过MutablePropertyValues类型的newPvs进行数据保存

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		if (pvs.isEmpty()) {
			return;
		}

		if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
			((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
		}

		MutablePropertyValues mpvs = null;
		List<PropertyValue> original;
		// 如果pvs 是 MutablePropertyValues 类型的封装
		if (pvs instanceof MutablePropertyValues) {
			mpvs = (MutablePropertyValues) pvs;
			// 如果 mpv 中的值类型已经转换完毕,则可以直接设置到BeanWrapper 中
			if (mpvs.isConverted()) {
				// Shortcut: use the pre-converted values as-is.
				try {
					bw.setPropertyValues(mpvs);
					return;
				}
				catch (BeansException ex) {
					throw new BeanCreationException(
							mbd.getResourceDescription(), beanName, "Error setting property values", ex);
				}
			}
			// 保存原始值,等待类型转换
			original = mpvs.getPropertyValueList();
		}
		else {
			// 保存原始值,等待类型转换
			original = Arrays.asList(pvs.getPropertyValues());
		}
		// 获取类型转换器
		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

		// Create a deep copy, resolving any references for values.
		// 准备进行深拷贝
		List<PropertyValue> deepCopy = new ArrayList<>(original.size());
		boolean resolveNecessary = false;
		// 遍历属性,将属性转换为对应类的对应属性类型
		for (PropertyValue pv : original) {
			// 如果已经转换之后直接保存
			if (pv.isConverted()) {
				deepCopy.add(pv);
			}
			else {
				// 进行类型转换
				String propertyName = pv.getName();
				Object originalValue = pv.getValue();
				if (originalValue == AutowiredPropertyMarker.INSTANCE) {
					Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
					if (writeMethod == null) {
						throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
					}
					originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
				}
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
				Object convertedValue = resolvedValue;
				
				boolean convertible = bw.isWritableProperty(propertyName) &&
						!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
				if (convertible) {
					convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
				}
				// Possibly store converted value in merged bean definition,
				// in order to avoid re-conversion for every created bean instance.
				if (resolvedValue == originalValue) {
					if (convertible) {
						pv.setConvertedValue(convertedValue);
					}
					deepCopy.add(pv);
				}
				else if (convertible && originalValue instanceof TypedStringValue &&
						!((TypedStringValue) originalValue).isDynamic() &&
						!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
					pv.setConvertedValue(convertedValue);
					deepCopy.add(pv);
				}
				else {
					resolveNecessary = true;
					deepCopy.add(new PropertyValue(pv, convertedValue));
				}
			}
		}
		if (mpvs != null && !resolveNecessary) {
			mpvs.setConverted();
		}

		// Set our (possibly massaged) deep copy.
		try {
			bw.setPropertyValues(new MutablePropertyValues(deepCopy));
		}
		catch (BeansException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Error setting property values", ex);
		}
	}

属性填充的总结:

 这个方法其实就是进行依赖注入然后方式的话就是有两种一个就是byType还有一个就是byName然后这个里面涉及到的自动装配的话后面会说

 initializeBean:

  这个代码一看比前几个不知道要简单多少,这个里面也涉及到了BeanPostProcessor. postProcessBeforeInitialization  BeanPostProcessor.postProcessAfterInitialization 方法的调用那么后面的话我会专门对于这个后置处理器写一篇文章进行介绍

@SuppressWarnings("deprecation")
	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		//这个就是运行所有的Aware接口实现的方法
		invokeAwareMethods(beanName, bean);

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			//使用的就是初始化前进行处理的后置处理器
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			//运行所有的初始化的方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			//调用初始化之后的后置处理器
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
       //进行返回已经完成初始化之后的Bean对象
		return wrappedBean;
	}

invokeAwareMethods:

这个方法见名知其义:这个就是进行Aware方法的执行:

1.如果实现了BeanNameAware接口那么就设置BeanName的值

2.如果实现了BeanClassLoaderAware接口那么就设置BeanClassLoader的值

3.如果实现了BeanFactoryAware接口那么就设置BeanFactory的值    就是这个简单一点都不难吧

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

invokeInitMethods:

 这个需要注意的就是说初始化方法的设置现在的话主要就是有下面的几种方法:

1.通过Init-method属性如:@Bean(init-Method="")   2.通过实现InitializingBean接口实现里面的afterPropertiesSet方法 顺序就是说afterPropertiesSet方法然后在执行属性Init-method属性方法当然在现在的话我们就是会通过使用@PostConstruct这个注解来进行标识

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {
       //这个就是看看这个Bean有没有是实现InitializingBean接口
		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
			//运行afterPropertiesSet方法
			((InitializingBean) bean).afterPropertiesSet();
		}

		if (mbd != null && bean.getClass() != NullBean.class) {
			//这个就是从RootDefinition获得初始话方法的名字
			String[] initMethodNames = mbd.getInitMethodNames();
			if (initMethodNames != null) {
				for (String initMethodName : initMethodNames) {
					if (StringUtils.hasLength(initMethodName) &&
							!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
							!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
						//执行这些初始化方法
						invokeCustomInitMethod(beanName, bean, mbd, initMethodName);
					}
				}
			}
		}
	}

测试:

public class TestBean implements InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("这个是初始方法中的afterPropertiesSet() ");
    }
    @PostConstruct
    public  void init(){
        System.out.println("这个是通过postConstruct注解的方法");
    }

    public  void testInit(){
        System.out.println("这个就是通过InitMethod属性的方法");
    }
}

结果:

初始化的总结:

   这个就是调用后置处理器里面的方法以及调用初始化的方法逻辑就是这么简单

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值