准备创建Bean

前面分析了获取单例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);
        }
    }

总结一下上面的代码干了什么事:

  1. 根据设置的class属性或者根据className来解析Class
  2. 把beanDefinition转换成RootBeanDefinition
  3. 对override属性进行标记及验证
  4. 应用初始化前的后处理器
  5. 创建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;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值