前面分析了获取单例Bean,回忆一下,首先先尝试从缓存中获取bean,如果缓存中没有,会先给beanName标记正在创建bean,然后调用ObjectFactory的getObject来创建bean,创建完成后会把beanName的标记状态去掉,更新三级缓存的数据.
那么分析到这里,最关键的就是那个getObject方法.上一篇文章也分析了,Spring调用了一个getSingleton的重载方法:public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory)
getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
})
这里使用lambda表达式直接重写了getObject方法.
所以其实调用的就是createBean(beanName, mbd, args);
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 锁定class,根据设置的class属性来根据className来解析Class
Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
// 转换成RootBeanDefinition
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
// 验证及准备覆盖的方法
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var9) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
}
Object beanInstance;
try {
// 给BeanPostProcessors一个机会来返回代理来替代真正的实例
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} catch (Throwable var10) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
}
try {
// 真正去创建bean的方法
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
throw var7;
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
}
}
总结一下上面的代码干了什么事:
- 根据设置的class属性或者根据className来解析Class
- 把beanDefinition转换成RootBeanDefinition
- 对override属性进行标记及验证
- 应用初始化前的后处理器
- 创建bean
Override
先来分析对override属性标记和验证的逻辑实现
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// 检查methodOverrides是否有值
if (hasMethodOverrides()) {
// 遍历
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
// 获取类中这个方法的个数
int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
// 如果是0,则抛出异常
if (count == 0) {
throw new BeanDefinitionValidationException(
"Invalid method override: no method with name '" + mo.getMethodName() +
"' on class [" + getBeanClassName() + "]");
}
// 如果是1个则标记方法没有被重写,避免参数类型检查的开销
else if (count == 1) {
mo.setOverloaded(false);
}
}
methodOverrides中存放的就是之前Spring解析bean的配置文件中配置的look-up和replace-method.这两个功能实现的原理是在bean实例话的时候如果检测到存在methodOverrides属性,会动态的为当前bean生成代理bean使用对应的拦截器为bean做增强处理,后面会详细介绍.
这里在检测的时候,顺便记录了是否重写了方法,如果重写了,Spring就需要根据参数来进行匹配,如果只有一个,说明没有被重写,Spring直接调用即可,所以这里既做了验证是否存在,又记录了是否被重写.
实例化的前置处理
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// 如果尚未解析
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
// 解析bean的class
Class<?> targetType = this.determineTargetType(beanName, mbd);
if (targetType != null) {
// 调用InstantiationAwareBeanPostProcessor中的postProcessBeforeInstantiation方法
bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 调用BeanPostProcessor的postProcessAfterInitialization方法
bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = bean != null;
}
return bean;
}
1、实例化前的后处理器应用
其实就是把AbstractBeanDefinition转换为BeanWrapper前的处理.给子类一个修改BeanDefinition的机会,也就是说当程序经过这个方法后,bean可能已经不是我们认为的bean了,而是或许成为了一个经过处理的代理bean,可能是通过cglib生成的,也可能是通过其他技术生成的.
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
Iterator var3 = this.getBeanPostProcessors().iterator();
while(var3.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var3.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
2、实例化后的后处理器
Spring中的规则是在bean的初始化后尽可能确保将注册的后处理器的postProcessAfterInitialization方法应用到改bean上,因为如果返回的bean不为空,不会再次经历普通bean的创建过程,所以只能这里应用后处理器的postProcessAfterInitialization方法.
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
Object current;
for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
BeanPostProcessor processor = (BeanPostProcessor)var4.next();
current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
}
return result;
}