【Spring源码开整】05. Spring Bean生成

Spring Bean生成

1.目标

​ 自然是来看看spring的bean生成流程的源码

​ 但是这流程就算不关注大量细节,也真的很长,后面考虑把这一篇再拆一拆

2.查找入口

private static void testSpring() {
   
    ClassPathXmlApplicationContext context = 
        new ClassPathXmlApplicationContext("beans.xml");
    Object alice = context.getBean("alice");
    System.out.println(alice);
}

断点打在getBean来看看

下面的代码会来到AbstractApplicationContext还记得之前讨论过的BeanFactory继承体系和它们的作用吗?可以看看第2篇和第3篇。

public Object getBean(String name) throws BeansException {
   
    //空实现
    assertBeanFactoryActive();
    //通过BeanFactory创建bean
    return getBeanFactory().getBean(name);
}

接着到了AbstractBeanFactory是不是很熟悉呢

public Object getBean(String name) throws BeansException {
   
    return doGetBean(name, null, null, false);
}

看见了doGetBean入口算是找到了

3.bean加载

乍一看下面的代码估计是很懵的状态,我们先来梳理下它到底干了什么再来深入其中的各个方法:

  1. 剥离工厂方法中真实的beanName,将alias转换为大名

    简单点说这一步就是为了获取到bean真名

  2. 创建前在缓存中获取bean,若获取到了就调用getObjectForBeanInstance获取真正的bean(前面有可能的是FactoryBean),返回bean;如果没有获取到进入步骤3

  3. 先检查先是否是Prototype scope正在创建的bean,如果是假设其存在循环依赖,直接抛异常

  4. 检查本BeanFactory是否有所需bean的BeanDefinition若没有交给parentBeanFactory解决bean的创建,如果有所需BeanDefiniton进入步骤5

  5. 获取BeanDefinition,检查其dependOn是否存在循环依赖。记录其依赖信息,先创建(getBean)它依赖的bean

  6. 分为singleton单例、prototype原型以及其他scope 3种来创建bean

  7. 如果是singleton就通过getSingleton(String beanName, ObjectFactory<?> singletonFactory),产生原始bean,再通过getObjectForBeanInstance获取真正的bean。ps:这里的ObjectFactory我们会在后面讨论spring解决单例属性注入循环依赖时再细说;

  8. 如果是prototype使用createBean来创建bean,在这个方法前后有对应callback接口的处理。同样的再通过getObjectForBeanInstance获取真正的bean

  9. 如果是其他scope,先获取Scope对象然后通过其get(String name, ObjectFactory<?> objectFactory)方法获取bean,通过getObjectForBeanInstance获取真正的bean

  10. 最终返回bean

protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
   
	//1. 获取bean的真名
    final String beanName = transformedBeanName(name);
    Object bean;

    // Eagerly check singleton cache for manually registered singletons.
    // 2.获取bean
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
   
        //获取真正的bean
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
   
        // 3.先检查先是否是Prototype scope正在创建的bean,如果是直接抛异常
        if (isPrototypeCurrentlyInCreation(beanName)) {
   
            throw new BeanCurrentlyInCreationException(beanName);
        }

        BeanFactory parentBeanFactory = getParentBeanFactory();
        // 4.检查本BeanFactory是否有所需bean的`BeanDefinition`,若没有,交给parentBeanFactory解决bean的创建
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
   
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            if (args != null) {
   
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else {
   
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
        }

        if (!typeCheckOnly) {
   
            markBeanAsCreated(beanName);
        }

        //5.获取beanDefinition
        final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
        checkMergedBeanDefinition(mbd, beanName, args);

        // 5.保证要生成bean依赖的bean先生成
        String[] dependsOn = mbd.getDependsOn();
        if (dependsOn != null) {
   
            for (String dep : dependsOn) {
   
                if (isDependent(beanName, dep)) {
   
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                }
                registerDependentBean(dep, beanName);
                getBean(dep);
            }
        }

        // Create bean instance.
        if (mbd.isSingleton()) {
   
            //7.创建Singleton scope bean
            sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
   
                @Override
                public Object getObject() throws BeansException {
   
                    return createBean(beanName, mbd, args);
                }
            });
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
        }

        else if (mbd.isPrototype()) {
   
            //8.创建prototype scope bean
            // It's a prototype -> create a new instance.
            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);
            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);
    	}
    }
    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
   
        return getTypeConverter().convertIfNecessary(bean, requiredType);
    }
    return (T) bean;
}

好了梳理了AbstractBeanFactorydoGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)我们接下来关注下面的几个方法实现

  1. getSingleton
  2. getObjectForBeanInstance
  3. createBean
  4. scope的get(String name, ObjectFactory<?> objectFactory)

3.1 getSingleton

在理解这个方法之前我们需要先了解3个缓存

  1. singletonObjects用来缓存单例bean
  2. earlySingletonObjects用来缓存早期的bean,就是还没有完成依赖注入的
  3. singletonFactories单例bean的ObjectFactory缓存

为什么要有这3个缓存呢?主要还是为了解决前面提到过的循环依赖问题。安装下面缓存调用的顺序singletonObjects->earlySingletonObjects->singletonFactories也有地方把它们称为3级缓存

/** Cache of singleton objects: bean name --> bean instance */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

	/** Cache of singleton factories: bean name --> ObjectFactory */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);

	/** Cache of early singleton objects: bean name --> bean instance */
	private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

	/** Set of registered singletons, containing the bean names in registration order */
	private final Set<String> registeredSingletons = new LinkedHashSet<String>(256);

接下来我们先读从缓存中获取单例bean,既然是从缓存中获取自然涉及到上面提及的3个缓存了。singletonObjects->earlySingletonObjects->singletonFactories按照这样的顺序,如果没有获取到想要的bean就要看看它的重载方法(AbstractBeanFactory流程)

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
   
			synchronized (this.singletonObjects) {
   
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
   
					ObjectFactory<?> singletonFactory = 
                        this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
   
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return (singletonObject != NULL_OBJECT ? singletonObject : null);
	}

下面是getSingleton的重载方法,从头加载bean。其实这个方法逻辑也很简单。流程有以下几步

  1. 尝试从缓存获取,获取到就返回

  2. 获取不到准备创建,先处理create前置方法

  3. 通过ObjectFactory来创建bean

  4. 先处理create后置方法

  5. 添加bean到缓存

  6. 返回bean

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
   
    synchronized (this.singletonObjects) {
   
        //1.尝试从缓存获取
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
   
            //2.获取不到准备创建,先处理create前置方法
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
   
                this.suppressedExceptions = new LinkedHashSet<Exception>();
            }
            try {
   
                //3. 通过ObjectFactory来创建bean
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            }
            catch (IllegalStateException ex) {
   
                // Has the singleton object implicitly appeared in the meantime ->
                // if yes, proceed with it since the exception indicates that state.
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
   
                    throw ex;
                }
            }
            finally {
   
                if (recordSuppressedExceptions) {
   
                    this.suppressedExceptions = null;
                }
                //4.先处理create后置方法
                afterSingletonCreation(beanName);
            }
            if (newSingleton) {
   
                //5. 添加bean到缓存
                addSingleton(beanName, singletonObject);
            }
        }
        //6. 返回bean
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }
}

到现在我们还在bean创建的控制流程中兜转,不过看到ObjectFactory.getObject算是看到了希望。这里大家知道前面AbstractBeanFactory对于这个接口实现的作用了吧。而BeanFactory的实现也很简单

new ObjectFactory<Object>() {
   
    @Override
    public Object getObject() throws BeansException {
   
        return createBean(beanName, mbd, args);
}

到这里我们可以把singleton和prototype的bean创建统合起来了,都是有create前后的处理+createBean

3.2 createBean

真正的准备创建来了(按spring的方法命名规律看到do才是真的创建),满怀欣喜的点进去一看AbstractBeanFactory并没有实现这个方法,想一想第3篇的实现,createBean方法的实现放在哪了?当然大家直接debug看会看的更清楚

protected abstract Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException;

跳到AbstractAutowireCapableBeanFactory,一如既往的保持spring的风格,这个方法内容不多,这里只关注下doCreateBean真正的创建bean

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
   
    RootBeanDefinition mbdToUse = mbd;

    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值