spring源码之InstantiationAwareBeanPostProcessor

spring源码之InstantiationAwareBeanPostProcessor

BeanPostProcessor的子接口,添加了实例化之前(before-instantiation)的回调,和实例化之后(after instantiation)的回调,但是这些操作发生在显示的设置属性或者自动注入之前发生。一般用来阻止具体的目标bean默认实例化,例如给目标bean创建代理对象(如惰性实例化),或者是用来给属性增加额外注入策略

这个接口一般是给框架本身用的,推荐尽可能实现BeanPostProcessor或者是继承InstantiationAwareBeanPostProcessorAdapter接口

InstantiationAwareBeanPostProcessor 源码

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {



	Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;


	boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;


	PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean,
			 String beanName) throws BeansException;

}

postProcessBeforeInstantiation方法

这个方法在bean实例化之前被调用,返回的对象可能是代替了目标对象的代理对象,有效的阻止了目标bean默认的实例化。也就是说,如果该方法返回的是non-null对象 ,这个bean的创建过程就会被短路,就不会执行postProcessAfterInitialization的方法和postProcessPropertyValues方法; 相反的如果方法返回值为null,则会继续默认的bean的实例化过程

AbstractAutowireCapableBeanFactory类的方法createBean中:


protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) 
								throws BeanCreationException {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			//如果bean已经被实例化了,就会继续之后bean的创建过程了,直接返回
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}

AbstractAutowireCapableBeanFactory类的方法populateBean中:


protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
	Object bean = null;
	if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
		// Make sure bean class is actually resolved at this point.
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			Class<?> targetType = determineTargetType(beanName, mbd);
			if (targetType != null) {
				bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
				if (bean != null) {
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
		}
		mbd.beforeInstantiationResolved = (bean != null);
	}
	return bean;
}

...


protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
	for (BeanPostProcessor bp : getBeanPostProcessors()) {
		if (bp instanceof InstantiationAwareBeanPostProcessor) {
			InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
			Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
			if (result != null) {
				return result;
			}
		}
	}
	return null;
}

可以发现,InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法如果返回不为空,整个对象的创建的过程就结束了,否则会执行这个bean正常的实例化过程

postProcessAfterInstantiation方法

这个方法在bean实例化(通过构造函数或者是工厂方法[via a constructor or factory method])之后被调用,但是在bean属性注入(property population)之前,如果方法返回值为true,则说明会在这个bean设置属性方法,即调用postProcessPropertyValues方法。返回false,则会跳过对象bean属性设置过程。一般的,实现类需要返回true,如果返回false,也阻止了其他InstantiationAwareBeanPostProcessor子类作用在bean的影响

AbstractAutowireCapableBeanFactory类的方法populateBean中:

boolean continueWithPropertyPopulation = true;

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
	for (BeanPostProcessor bp : getBeanPostProcessors()) {
		if (bp instanceof InstantiationAwareBeanPostProcessor) {
			InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
			if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
				continueWithPropertyPopulation = false;
				break;
			}
		}
	}
}

if (!continueWithPropertyPopulation) {
	return;
}

可以发现,只要postProcessAfterInstantiation方法返回为false,其他作用在这个目标bean的所有的InstantiationAwareBeanPostProcessor实例都不会被执行,自然也就不会执行对bean属性注入的过程了

postProcessPropertyValues方法

这个方法通常是给目标bean设值,这个过程发生只有在postProcessAfterInstantiation方法的结果返回true才会被执行

AbstractAutowireCapableBeanFactory类的方法populateBean中:


boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

if (hasInstAwareBpps || needsDepCheck) {
	PropertyDescriptor[] filteredPds = 
			filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
	if (hasInstAwareBpps) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = 
									(InstantiationAwareBeanPostProcessor) bp;
				pvs = ibp.postProcessPropertyValues(pvs, filteredPds, 
								bw.getWrappedInstance(), beanName);
				if (pvs == null) {
					return;
				}
			}
		}
	}
	if (needsDepCheck) {
		checkDependencies(beanName, mbd, filteredPds, pvs);
	}
}

applyPropertyValues(beanName, mbd, bw, pvs);

可以看到,如果这个方法返回为空,也不会对目标bean设值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值