《Spring设计思想》11-如果上天再给你一次机会
第9节书中写道:紫霞仙子的剑离秦祥林的喉咙只有0.01厘米,但是至尊宝撒了一个谎,这个谎导致紫霞仙子彻底的爱上了他,但是他万万没想到,这是一个悲剧的开始。紫霞仙子还是被捉去被强迫成亲,而他自己拿了月光宝盒逃跑。。。
所以第10节紫霞仙子还是默认进行了实例化,这个时候她穿好了嫁衣,马上就要拜堂了。他的意中人到底能不能来接他
这一节我们书接上文,继续看看bean被实例化之后有什么操作。
还是AbstractAutowireCapableBeanFactory.createBean(String beanName,RootBeanDefinition mbd,Object[] args)方法
调用AbstractAutowireCapableBeanFactory.doCreateBean(String beanName,RootBeanDefintion mbd,Object[] args)方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.实例化bean
BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
// Initialize the bean instance. 初始化bean
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
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);
}
}
return exposedObject;
}
方法中可以看到bean在实例化之后要执行初始化操作。
1:populateBean(beanName,mbd,instanceWrapper);注入bean的配置属性
2:exposedObject = initializeBean(beanName,exposedObject,mbd);初始化bean,调用aware的回调接口,和beanPostProcessor
简单的看下populateBean(beanName,mbd,instanceWrapper);
/**
* Populate the bean instance in the given BeanWrapper with the property values
* from the bean definition.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param bw the BeanWrapper with bean instance
*/
@SuppressWarnings("deprecation") // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 着重强调,我要给至尊宝一次机会,让他阻止当前的婚礼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.
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;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
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;
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 (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
看到属性:continueWithPropertyPopulation的时候,我心里流下了感动的泪水,这个地方是紫霞仙子给至尊宝留下的一个机会,让他可以终止当前的婚礼,还是前面讲到的接口InstantiationAwareBeanPostProcessor:
第9节描述的是postProcessorBeforeInstantiation方法,这个地方调用的是posrProcessorAfterInstantiation(Object,String)
看简单的实现
public class BeanInstantiaitionAwareImpl implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
// Assert.isNull(beanClass,"beanClass不能为空");
if(ObjectUtils.nullSafeEquals(beanClass, SuperUser.class)){
SuperUser superUser = new SuperUser();
superUser.setName("一个船新的版本");
superUser.setAge(22);
return superUser;
}
//默认什么都不做,返回null,继续下一步实例化
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if(bean.getClass().equals(User.class)){
User user = (User) bean;
user.setName("至尊宝");
user.setAge(589);
return false;
}
//默认返回true,什么也不做,继续下一步 初始化
return true;
}
}
断点调试:
调用堆栈
不再继续populateBean方法,
看输出结果:
至尊宝来了:
到这里我们看到,InstantiationAwareBeanPostProcessor的两个方法
postProcessorBeforeInstantiation在实例化之前调用
postProcessorAfterInstantiation在实例化之后,初始化之前调用。
上一篇: Hibernate4之事务机制
下一篇: Java学习(5)——泛型和集合