经过上一节的分析,我们完成了通过xmlBeanFactory容器初始化的内容,后面会继续讲解关于AplicationContext容器初始化的讲解。这一节我们主要分析的是bean的加载,及getBean方法的过程及原理实现。首先我们整体看一下getBean方法真正的执行者doGetBean方法,该方法在AbstractBeanFactory中,下面进入正题!
@Override
public Object getBean(String name) throws BeansException {
//我们从源码中不能难到,真正干事情的都是以do开头的
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly){
//提取对应的beanName,比如说有alias等等
final String beanName = transformedBeanName(name);
Object bean;
/*检测缓存中或者实例工厂中是否有对应的实例,在创建单例bean的时候会存在依赖注入的情况,
*而在创建依赖的时候为了避免循环依赖,spring的原则是不等bean创建完成就会将创建bean的
*ObjectFactory提早曝光,也就是将其放入到缓存中,
*一旦下个bean创建时候需要依赖上个bean则直接使用ObjectFactory,直接尝试从缓存获取或者
*singletonFactor中的ObjectFactory中获取
*/
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//返回对应实例,有时候不是返回实例本身,有可能是FactoryBean的getObject方法之类
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//只有单例才会尝试解决循环依赖
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//如果beanDefinitionMap中不包括beanName则尝试从parentBeanFactor中检测
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
if (args != null) {
// 递归到BeanFactory中找
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//如果不是仅仅做类型检查则是创建bean,这里要记录
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//将GernericBeanDefinition转换为RootBeandefinition,如果指定BeanName是子Bean的话会合并父类的属性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//若存在依赖则需要递归实例化依赖的bean.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
//缓存依赖调用
registerDependentBean(dep, beanName);
getBean(dep);
}
}
// 实例化mbd本身.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
}
});
//返回对应实例,有时候不是返回实例本身,有可能是FactoryBean的getObject方法之类
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
//prototype模式创建bean
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
//指定的scope上实例bean
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
}
//检查需要的类型是否符合bean的实际类型.
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
}
return (T) bean;
}
不难看出bean的加载经历了一个相当复杂的过程,从注释可以粗略的了解整个spring加载bean的过程。大致步骤如下:
- 转换对应的bean:传入的参数可能是别名,也有可能是FactoryBean,所以需要解析
- 尝试从缓存中加载单例:单例在容器中只会创建一次,后面直接从单例缓存中获取。当然这里只是尝试加载,首先尝试从缓存中加载,然后再尝试从singletonFactories中加载,因为在创建单例Bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,不等bean创建完成就会将bean的ObjectFactory提早曝光加入到缓存中,一旦下一个需要则直接使用ObejctFactory
- bean的实例化:记录的只是最原始的bean状态,不一定是我们最终想要的bean,比如factoryBean
- 原型模式的依赖检查
- 检测parentBeanFatory
- 将GernericBeanDefinition转换为RootBeanDefinition:转换同时如果父类bean不为空的话会合并父类属性
- 寻找依赖:在初始化某一个bean的时候首先会初始化这个bean所对应的依赖
- 针对不同的scope进行bean的创建
- 类型转换
下面我们就将注意进行分析
缓存中获取单例Bean
跟踪代码来到DefaultSingletonBeanRegistry
public Object getSingleton(String beanName) {
//参数true表示允许早期依赖
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//检查缓存中是否存在实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//如果为空,则锁定全局变量实例
synchronized (this.singletonObjects) {
//如果此bean正在加载则不处理
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
//当某些方法需要提前初始化的时候会将对应的objectFactory存在singletonFactories
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//调用预先设定的getObject方法
singletonObject = singletonFactory.getObject();
//记录在缓存中,以下两者互斥
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
这个方法首先从singletonObjects中获取实例,获取不到再到erlySingletonObejcts中获取,还获取不到就到singletonFactoryies中获取ObjectFatory的getObject获取bean
Bean的实例化
getObjectForBeanInstanse方法在getBean中是个高频少用的方法,无论从缓存中获取还是根据不同的scope策略加载,总之,我们得到bean的实例后第一步就是调用此方法,检测当前bean 是否是FactoryBean,如果是,那么需要调用该bean对应的getObject方法作为返回值。
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
//如果指定的name是工厂相关(以&为前缀)且又不是FactoryBean类型则验证不通过
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
//加载FactoryBean
Object object = null;
if (mbd == null) {
//从缓存中加载bean
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// 到这儿已经知道是FactoryBean类型.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// 检测beanDifinitionMap中是否已经定义了beanName.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
//是否是用户定义的而不是应用程序本身定义的
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
- 对FactoryBean正确性的验证
- 对非FactoryBean不做任何处理
- 对bean进行转换
- 将从Factory中解析bean的工作委托给getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
object = doGetObjectFromFactoryBean(factory, beanName);
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (object != null && shouldPostProcess) {
try {
//调用ObjectFactory的后处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
}
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
}
return (object != NULL_OBJECT ? object : null);
}
}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (object != null && shouldPostProcess) {
try {//调用ObjectFactory的后处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
}
return object;
}
}
此方法做了一件事就是返回的bean如果是单例,就必须保证全局唯一性,同时利用缓存来提升性能,然后调用了ObejctFactory的后处理器对object进行处理,下面进入doGetObjectFromFactoryBean方法
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
//需要权限验证
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
return factory.getObject();
}
}, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
//直接调用getObject方法
else {
object = factory.getObject();
}
}
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
return object;
}
返回了这个factory.getObejct后回到下面看看后处理,跟进代码来到AbstractAutowireObjectFromFactoryBean中
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
后面会做详细描述,在此我们只要了解尽可能保证所有bean初始化后都会调用注册的BeanPostProcessor的postProcessAfterInitialization方法进行处理,在实际开发过程中大可以针对此特性设计自己的业务逻辑
获取单例
上面我们分析了从缓存中获取单例,那么如果缓存中不存在加载的单例bean就是要重头开始bean的加载过程了
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
//锁住全局变量
synchronized (this.singletonObjects) {
//检测是否已经加载
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
}
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<Exception>();
}
try {
//初始化bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
//加入缓存
addSingleton(beanName, singletonObject);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
- 检查缓存是否已经加载过
- 若没有加载,则记录beanName的正在加载状态
- 加载单例前记录加载状态(beforeSingletonCreation),便于对循环依赖进行检测
- 实例化bean
- 加载单例后处理的方法(afterSingletonCreation),移除正在加载状态
- 将结果记录至缓存并删除bean加载过程中的各种辅助状态
- 返回处理结果,核心只是调用了ObjectFactory中的createBean方法,所以我们要回到doGetBean方法中的createBean中去
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
//锁定class,根据设置的class或者className来解析class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 验证及准备覆盖的方法.
try {
mbdToUse.prepareMethodOverrides();
}
try {
//给BeanPostProcessors机会来返回一个代理实例
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
//具体创建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
- 根据设置的class属性或者根据className属性来解析Class
- 对override属性进行标记及验证
- 应用初始化的后处理器
- 创建bean
在调用doCreateBean之前调用了resolveBeforeInstantiation方法对BeanDefinition中的属性做些前置处理,当前置处理后返回的不为空,那么直接略过创建而直接返回结果,我们熟知的Aop功能呢=就是基于这里判断的。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
//如果尚未被解析
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
此方法中最吸引我们的无疑是applyBeanPostProcessorsBeforeInstantiation以及applyBeanPostProcessorsAfterInstantiation。无非是对后处理器中的所有InstantiationAwareBeanPostProcessor类型的后处理器进行postProcessBeforeInstantiation方法和BeanPostProcessor的postProcessAfterInitialization方法的调用
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
循环依赖
对于构造循环依赖,spring无法处理,对于setter循环依赖是通过spring提前暴露刚完成构造器注入但未完成其他步骤的bean来完成的,而且只能是单例作用域的bean,通过提前暴露一个单例工厂方法,从而使其他bean能引用到该bean。下面我们接着上面的如果后置处理器返回结果为空后的doCreateBean方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//根据指定bean使用对应的策略创建新的实例,如:工厂方法,构造函数自动注入、简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//应用MergedBeanDefinitionPostProcessor改变beanDefinition
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
mbd.postProcessed = true;
}
}
// 是否需要提早曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
//其中AOP就是在这儿将advice动态植入bean中,若没有则直接返回bean
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//对bean进行填充,注入各个属性,可能存在依赖其他bean,递归调用初始化bean
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
//earlyingletonReference 只有检测到有循环依赖的情况下才不为空
if (earlySingletonReference != null) {
//如果exposedObject没有在初始化方法中被改变,也就是没有被增强
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
//检测依赖
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
//bean创建后其所依赖的bean一定创建,若actualDependentBeans不为空说明当前bean创建后其依赖的bean却没有创建完,也就是存在循环依赖
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName)
}
}
}
}
// Register bean as disposable.
try {
//根据scope注册bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
- 如果是单例则需要首先清除缓存
- 实例化bean,将BeanDefinition转换为BeanWraper
- MergedBeanDefinitionPostProcessor的应用:bean合并后的处理,Autowired注解正式通过此方法实现诸如类型的预解析
- 依赖处理
- 填充属性
- 循环依赖检查
- 注册DisosableBean
- 完成创建并返回
参考:《sping源码深度解析》