一个真正干活的函数其实是以do开头的,而我们错觉的函数,其实只是从全局的角度去做一些统筹的工作。这个规律对于createBean也不例外,那么createBean函数中做了那些准备工作。
protected Object createBean(final String beanName,final RootBeanDefinition mbd,final Object[] args) throws BeanCreationException
// 锁定class,根据设置的class属性或者根据className来解析Class
// 验证及准备覆盖的方法
// 给BeanPostProcessors一个机会返回代理来替代真正的实例
// 调用doCreateBean()方法
}
从代码中可以总结出函数完成的具体步骤及功能。
a.根据设置的class属性或者根据className来解析Class;
b.对override属性进行标记及验证。
1.处理override属性
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException
// 获取对应类中方法名的个数
// 如果个数为1时,标记MethodOverride暂未被覆盖,避免参数类型检查的开销
}
通过以上两个函数的代码实现了之前反复提到过的,在Spring配置中存在lookup-method和replace-method两个配置功能,而这个配置的加载其实就是将配置统一存放在BeanDefinition中的methodOverrides属性中,这两个功能的实现原理其实是在bean实例化的时候,如果检测到存在methodOverrides属性,会动态地为当前bean生成代理并使用对应的拦截器为bean做增强处理。
2.实例化的前置处理
在真正调用doCreate方法创建bean的实例前使用了这样一个方法resolveBeforeInstantiation(beanName,mbd)对BeanDefinition中的属性做前置处理。
当经过前置处理后返回的结果如果不为空,那么会直接略过后续的Bean的创建而直接返回结果。这个特性判断虽然很容易被忽略,但是却起着至关重要的作用。
protected Object resolveBeforeInstantiation(String beanName,RootBeanDefinition mbd)
此方法中最吸引人的无疑是两个方法:applyBeanPostProcessBeforeInstantiation以及applyBeanPostProcessAfterInitialization。
这两个方法实现非常简单,无非是对后处理器中所有InstantionAwareBeanPostProcessor类型的后处理器进行postProcessBeforeInstantiation方法和BeanPostProcessAfterInitialization方法的调用。
a.实例化前的后处理器的应用
bean的实例化前调用,就是将AbstractBeanDefinition转换为BeanWrapper前的处理,给子类一个修改BeanDefinition的机会,也就是说当程序经过这个方法后,bean可能已经不是我们认识的bean了,而是或许称为 一个经过处理的代理bean,可能通过cglib生成的,也可以是其他技术生成的。
b.实例化后的后处理器的应用
Spring中的规则是在bean的初始化后尽可能保证将注册的后处理器的postProcessAfterInitialization方法应用到该bean中,因为如果返回的bean不为空,那么便不会再次经历普通bean的创建过程,所以只能在这里应用后处理器的postProcessAfterInitialization方法。
标签:处理,创建,bean,实例,处理器,准备,方法,属性 From: https://blog.51cto.com/u_11315052/7537250