spring创建bean源码

一:doGetBean方法

1.判断beanName是否为空,为空抛异常,再判断beanName是否以&开头是的话去掉&。

2.执行getSingleton(beanName),获取bean的登记式单例,如果需要的单例不为空的话返回已存在的单例。(返回语句在方法结尾处)

if ((sharedInstance != null) && (args == null)) {
            if (this.logger.isDebugEnabled()) {
                  if (isSingletonCurrentlyInCreation(beanName)) {
                      this.logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
                  }
                  else{
                      this.logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                  }
            }
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

3.未获取到单例的话去获取bean的beanDefination,如果beanDefination中不存在指定bean的beanDefination并且父级容器不为空则去父级容器中请求bean

if ((parentBeanFactory != null) && (!containsBeanDefinition(beanName)))
{
    String nameToLookup = originalBeanName(name);
    if (args != null)
    {
        return parentBeanFactory.getBean(nameToLookup, args);
    }

    return parentBeanFactory.getBean(nameToLookup, requiredType);
}

4.获取当前请求的bean所依赖的所有bean名称,不为空的话去递归调用getBean方法

String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
    for (int i = 0; i < dependsOn.length; i++) {
        String dependsOnBean = dependsOn[i];
        getBean(dependsOnBean);
        registerDependentBean(dependsOnBean, beanName);
    }

}

5.如果是单例模式创建单例模式的bean,如果是原型模式创建原型模式的bean,否则根据bean定义资源中配置的生命周期范围实例化bean。

        web应用程序中比较常用,比如request,session,application等生命周期。

        if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, new ObjectFactory() {
                public Object getObject() throws BeansException {
                    try {
                        return AbstractBeanFactory.this.createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex)
                    {
                        AbstractBeanFactory.this.destroySingleton(beanName);
                        throw ex;}
                }
            });
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
        }


        else if (mbd.isPrototype())
        {
            Object prototypeInstance = null;
            try {
                beforePrototypeCreation(beanName);
                prototypeInstance = createBean(beanName, mbd, args);
            }
            finally {
                afterPrototypeCreation(beanName);
            }
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
        }

        else
        {
            String scopeName = mbd.getScope();
            Scope scope = (Scope)this.scopes.get(scopeName);
            if (scope == null)
                throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
            try
            {
                Object scopedInstance = scope.get(beanName, new ObjectFactory() {
                    public Object getObject() throws BeansException {
                        AbstractBeanFactory.this.beforePrototypeCreation(beanName);
                        try {
                            return AbstractBeanFactory.this.createBean(beanName, mbd, args);
                        }
                        finally {
                            AbstractBeanFactory.this.afterPrototypeCreation(beanName);
                        }
                    }
                });
                bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);

 

二:doCreateBean方法(AbstractAutowireCapableBeanFactory)

1.用beanName和beanDefination为参数创建实例对象

instanceWrapper = createBeanInstance(beanName, mbd, args);

      三种方式实例化:

1》.如果rootBeanDefination的工厂方法名不为空,用工厂方法模式创建实例。

if (mbd.getFactoryMethodName() != null)  {
2》.如果方法传进来的参数args不为空使用自动装配方式实例化,容器的自动装配是根据参数类型匹配bean的构造方法。

 要想不为空,从getBean开始就得传

3》.使用默认的无参构造方法实例化bean

此方式最常用:beandefination判断MethodOverrides()类中hashset集合性质的一个属性中维护的MethodOverride类是否为空,为空的话用反射机制来实例化,否则用CGLIB动态代理技术来进行实例化。

2.初始化bean对象,依赖注入在此触发

exposedObject 在初始化完成后返回作为依赖注入完成后的bean

Object exposedObject = bean;
try {

将bean实例对象封装,并且将bean定义中配置的属性值赋值实例对象
populateBean(beanName, mbd, instanceWrapper);

初始化bean对象
exposedObject = initializeBean(beanName, exposedObject, mbd);
}

http://www.cnblogs.com/davidwang456/p/4192318.html (BeanDefination是接口)

populateBean()方法:填充bean

1》.获取容器解析bean定义资源时给beanDefination设置的属性值
PropertyValues pvs = mbd.getPropertyValues();

2》.设置属性前先调用后置处理器
http://www.cnblogs.com/sishang/p/6576665.html(后置处理器:如果要在bean实例化、初始化前后加一些自己的逻辑处理,需要定义一个或多个BeanPostProcessor的实现类来,然后注册到IOC容器中。)

3》.首先处理autoaire自动装配的注入
使用取得的当前Bean的属性名作为Bean的名字,向IoC容器getBean ,然后把从容器得到的Bean设置(setPropertyValues)到当前Bean的属性中去

4》.解析
判断属性值是否需要解析,比如属性值为另一个bean的引用,需要先解析再注入

5》.注入:依赖注入的过程就是将bean对象实例设置到它依赖的bean对象属性上去。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值