spring最为基础也是极为重要的一个元素单位便是bean,bean由开发者编写的普通java类经过spring按照开发者指定的规则生成而来,作为pojo的替代对象进行使用,之前的学习中已经知道spring通过doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)方法来创建bean实例,简单回顾一下方法里三个参数的作用:
beanName:bean的名称,也是bean的标识
RootBeanDefinition mbd:一个用来描述bean的对象
Object[] args:创建构造函数和工程方法的时候用到的一些参数
为了写出更加出彩、难以发现的bug还需要从源码开始学习。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
//初始化这个bean的包装,在bean创建之后会由这个对象来进行包装,对象内部会包含bean的实例和BeanDefinition(用来描述bean的对象)以及一个属性编辑器
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//如果这个bean是单例的,就尝试着从缓存里面获取bean包装对象
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//这里就是创建bean对象的地方,万物起始之处
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//获取bean对象
final Object bean = instanceWrapper.getWrappedInstance();
//获取bean对象的类型
Class> beanType = instanceWrapper.getWrappedClass();
//NullBean的意思是内部空的bean
if (beanType != NullBean.class) {
//在描述文件中赋值上bean的类型
mbd.resolvedTargetType = beanType;
}
//获取后处理的锁
synchronized (mbd.postProcessingLock) {
//是否已经处理过后处理器
if (!mbd.postProcessed) {
try {
//执行合并bean定义的后处理器
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
//修改状态,已经执行过后处理器了,不需要再重复劳动
mbd.postProcessed = true;
}
}
//判断spring是否应该过早的暴露的bean对象,用来提供对循环依赖的支持。
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//注册到单例工程中,getEarlyBeanReference这个方法会将aop动态织入bean中,如果没有aop就直接返回bean
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject = bean;
try {
//填充bean的属性
populateBean(beanName, mbd, instanceWrapper);
//初始化bean
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);
}
}
//判断是否过早的暴露出去了,就是之前放入缓存的地方
if (earlySingletonExposure) {
//从singletonFactories中获取一下
Object earlySingletonReference = getSingleton(beanName, false);
//如果获取到了实例,
if (earlySingletonReference != null) {
//并且这个实例和初始化之后的bean对象是同一个,就说不是一个代理的bean对象
if (exposedObject == bean) {
//把缓存中的bean赋值给exposedObject
exposedObject = earlySingletonReference;
}
//检查依赖这个bean的bean是否都已经初始化好了
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
//获取依赖当前bean的beanname
String[] dependentBeans = getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
//检查这些需要依赖的bean,删除掉那些用于类型检测的bean,如果不是的加入到“actualDependentBeans”缓存中
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
//如果缓存不是空的就抛出异常
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
//根据配置的scopse属性,对bean进行注册,如果配置了destroy-method,也需要在这里注册,方便销毁bean的时候调用
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
//返回这个bean
return exposedObject;
}
抛开那些烦人的异常处理和日志,回头整理一下这个方法的主要思路:
如果是单例的bean就先清除掉缓存
实例bean,将beanDefinition(bean的描述对象)转化成beanWrapper(bean的包装对象)
执行MergedBeanDefinitionPostProcessor的处理,主要作用就是对@Autowired和@Value注解做预处理。
解决循环依赖的问题
对bean的属性进行填充
检查是否发生循环依赖问题
注册bean
返回bean
方法虽然很长,但是思路清晰,过程简单,当我们了解了循环依赖和spring的解决之道后,这个方法看起来就会很轻松,也能专注于最为重要的一步,就是第二步中的createBeanInstance()方法。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//解析获得bean的class对象
Class> beanClass = resolveBeanClass(mbd, beanName);
//如果这个beanclass是空的,或者修饰符不是public,或者没有权限访问构造函数和方法,就抛出异常
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
//初始化supplier,这个对象可以把bean包装成beanWrapper
Supplier> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//如果工厂方法不为空,就根据工厂方法初始化策略
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
//是否曾经创建过这个bean
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
//resolvedConstructorOrFactoryMethod不为空的话,曾经就创建过这个bean
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
//constructorArgumentsResolved为true说明之前采用的是构造函数自动注入的方式
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//如果曾经解析过,就使用之前的解析好的构造方法
if (resolved) {
if (autowireNecessary) {
//使用构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
//使用默认的构造函数
return instantiateBean(beanName, mbd);
}
}
// 走到这里说明是第一次创建bean,获取构造函数
Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//构造函数的方式进行加载
return autowireConstructor(beanName, mbd, ctors, args);
}
//如果设置了指定的构造函数,就是用这个构造函数进行加载
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 直接初始化bean
return instantiateBean(beanName, mbd);
}
spring实例化bean的细节还是相当复杂的,spring将逻辑提取到createBeanInstance()方法中,将具体实现封装到autowireConstructor()和instantiateBean()的方法中。
查看BeanDefinition中指定了Supplier或者指定了工厂方法,就直接从这里跳过去,并且返回结果。
解析构造函数,并通过构造函数进行实例化。一个类可能有多个构造函数,每个构造函数的参数不同,spring根据参数数量和类型判断最终使用哪个构造函数进行实例化。但是判断的过程是个比较消耗性能的步骤,spring采用了一个缓存的机制,减少重复的解析。
autowireConstructor()和instantiateBean()两个方法的冗长又极为复杂,让人难以理解又昏昏欲睡,所以我们还是留到下一次再讲,我先睡一会(¦3[▓▓] 果然看源码是最好的安眠药。。。。