上一节说完BeanDefinition中的beanClass属性从String转换成了Class。这一节继续看看beanDefinition发生了什么,
回到上一节的方法createBean:
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
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();
}
try {
// 曾经有一份真挚的爱情摆在我面前,我没有珍惜。。。Give BeanPostProcessors a
//chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
}
}
resolveBeanClass之后,有一段代码是给编程人员一个机会,打断正常的bean的实例化过程,自定义实例化操作。所以名字叫bean创建的过程的仙履奇缘,需要实现InstantiaitionAwareBeanPostProcess接口,
仔细观察一下InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor 继承了 BeanPostProcessor 接口,接口说明上简单的介绍了一下,这个接口是一个回调接口,定义了在bean的实例化之前和之后被调用的两个方法,而且是在注入bean的属性之前。
所以这一点很重要,postProcessBeforeInitialization是在注入配置属性(properties inject)之前做用到的。看简单的示例
public class BeanInstranitionAwareImpl 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;
}
return null;
}
}
可以上面的实现,在beanClass是SuperUser的类型时,直接返回一个全新的对象。如果不想特殊处理bean,可以默认返回null,表示该bean还是默认使用spring的实例化方法。
下面是仙履奇缘中至尊宝的英文版本:
* Subinterface of {@link BeanPostProcessor} that adds a before-instantiation callback,
* and a callback after instantiation but before explicit properties are set or
* autowiring occurs.
*
* <p>Typically used to suppress default instantiation for specific target beans,
* for example to create proxies with special TargetSources (pooling targets,
* lazily initializing targets, etc), or to implement additional injection strategies
* such as field injection.