第9節書中寫道:beanDefinition實例化之前給了至尊寶一個機會,讓他帶自己離開,不再進行默認的實例化,但是至尊寶啥也沒做
所以第10節beanDefinition還是默認進行了實例化,生成了bean。這個時候紫霞穿好了嫁衣,馬上就要拜堂了。他的意中人到底能不能來接他?
這一節我們書接上文,繼續看看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在實例化之後,初始化之前調用。