Spring源码解析笔记4——bean的加载

首先先说一下FactoryBean。Spring中的两种bean,一种是普通的Bean,另外一种是FactoryBean,FactoryBean是Spring留给使用者自己定义实例化bean的逻辑的接口。

FactoryBean接口源码:

package org.springframework.beans.factory;

public interface FactoryBean<T> {
    T getObject() throws Exception;//返回由FactoryBean创建的实例

    Class<?> getObjectType();//返回FactoryBean创建的bean实例的类型

    boolean isSingleton();
}

FactoryBean的使用实例:

public class Car {

    private int maxSpeed;
    private String brand;
    private double price;

    //此处省略get/set方法。
}
public class CarFactoryBean implements FactoryBean<Car>{

    private String carInfo;

    @Override
    public Car getObject() throws Exception {

        Car car = new Car();
        String infos[] = carInfo.split(",");
        car.setBrand(infos[0]);
        car.setMaxSpeed(Integer.parseInt(infos[1]));
        car.setPrice(Double.parseDouble(infos[2]));

        return car;
    }

    @Override
    public Class<?> getObjectType() {
        return Car.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }


    public String getCarInfo() {
        return carInfo;
    }

    public void setCarInfo(String carInfo) {
        this.carInfo = carInfo;
    }
}
 <bean id="car" class="com.msmk.cloud.spring.demo02.CarFactoryBean" carInfo="跑车,400,200"/>

按照上述操作后,spring在调用getBean(“car”)的时候,会通过类反射机制发现CarFactoryBean实现了FactoryBean的接口,这时Spring容器就调用CarFactoryBean的getObject()方法返回,如果需要返回CarFactoryBean的实例,则需要在使用getBean(beanName)时,在beanName前面加上&前缀,例如:getBean(“&car”)。

从MyTestBean bean = (MyTestBean)bf.getBean(“myTestBean”)开始进行追踪。

//跟踪AbstractBeanFactory实现的getBean方法:

public Object getBean(String name) throws BeansException {
        return this.doGetBean(name, (Class)null, (Object[])null, false);
    }
protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {

        //提取真正的beanName,此处的name可能是别名,可能是FactoryBean
        final String beanName = this.transformedBeanName(name);

        //尝试从缓存,SingletonFactories中的ObjectFactory中获取。
        Object sharedInstance = this.getSingleton(beanName);
        Object bean;
        if(sharedInstance != null && args == null) {
            if(this.logger.isDebugEnabled()) {
                if(this.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,有时候BeanFactory的情况并不是直接返回实例本身,而是返回指定方法返回的实例。
            bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
        } else {

            //检测循环依赖
            if(this.isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            BeanFactory ex = this.getParentBeanFactory();

            //在parentBeanFactory不为null的情况下,如果beanDefinitionMap中没有找到beanName,则尝试着去parentBeanFactory寻找。
            if(ex != null && !this.containsBeanDefinition(beanName)) {
                String var24 = this.originalBeanName(name);
                //递归寻找
                if(args != null) {
                    return ex.getBean(var24, args);
                }

                return ex.getBean(var24, requiredType);
            }

            //如果不是仅仅做类型检查则是创建bean,这里要进行记录。
            if(!typeCheckOnly) {
                this.markBeanAsCreated(beanName);
            }

            try {
                //将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition,如果指定BeanName是子bean的话同时会合并父类的相关属性。
                final RootBeanDefinition ex1 = this.getMergedLocalBeanDefinition(beanName);
                this.checkMergedBeanDefinition(ex1, beanName, args);
                String[] dependsOn = ex1.getDependsOn();
                String[] scopeName;

                //如果存在依赖则需要递归实例化依赖的bean。
                if(dependsOn != null) {
                    scopeName = dependsOn;
                    int scope = dependsOn.length;

                    for(int ex2 = 0; ex2 < scope; ++ex2) {
                        String dep = scopeName[ex2];
                        if(this.isDependent(beanName, dep)) {
                            throw new BeanCreationException(ex1.getResourceDescription(), beanName, "Circular depends-on relationship between \'" + beanName + "\' and \'" + dep + "\'");
                        }

                        //缓存依赖调用。
                        this.registerDependentBean(dep, beanName);
                        this.getBean(dep);
                    }
                }

                //以下的if是根据scope的不同,singleton和prototype不同情况进行处理。
                if(ex1.isSingleton()) {
                    sharedInstance = this.getSingleton(beanName, new ObjectFactory() {
                        public Object getObject() throws BeansException {
                            try {
                                return AbstractBeanFactory.this.createBean(beanName, ex1, args);
                            } catch (BeansException var2) {
                                AbstractBeanFactory.this.destroySingleton(beanName);
                                throw var2;
                            }
                        }
                    });
                    bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, ex1);
                } else if(ex1.isPrototype()) {
                    scopeName = null;

                    Object var25;
                    try {
                        this.beforePrototypeCreation(beanName);
                        var25 = this.createBean(beanName, ex1, args);
                    } finally {
                        this.afterPrototypeCreation(beanName);
                    }

                    bean = this.getObjectForBeanInstance(var25, name, beanName, ex1);
                } else {
                    String var26 = ex1.getScope();
                    Scope var27 = (Scope)this.scopes.get(var26);
                    if(var27 == null) {
                        throw new IllegalStateException("No Scope registered for scope name \'" + var26 + "\'");
                    }

                    try {
                        Object var28 = var27.get(beanName, new ObjectFactory() {
                            public Object getObject() throws BeansException {
                                AbstractBeanFactory.this.beforePrototypeCreation(beanName);

                                Object var1;
                                try {
                                    var1 = AbstractBeanFactory.this.createBean(beanName, ex1, args);
                                } finally {
                                    AbstractBeanFactory.this.afterPrototypeCreation(beanName);
                                }

                                return var1;
                            }
                        });
                        bean = this.getObjectForBeanInstance(var28, name, beanName, ex1);
                    } catch (IllegalStateException var21) {
                        throw new BeanCreationException(beanName, "Scope \'" + var26 + "\' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var21);
                    }
                }
            } catch (BeansException var23) {
                this.cleanupAfterBeanCreationFailure(beanName);
                throw var23;
            }
        }

        //检查需要的类型是否符合bean的实际类型。
        if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
            //将返回的bean转换为requiredType类型
            try {
                return this.getTypeConverter().convertIfNecessary(bean, requiredType);
            } catch (TypeMismatchException var22) {
                if(this.logger.isDebugEnabled()) {
                    this.logger.debug("Failed to convert bean \'" + name + "\' to required type \'" + ClassUtils.getQualifiedName(requiredType) + "\'", var22);
                }

                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        } else {
            return bean;
        }
    }

bean加载的时序图:

《Spring源码解析笔记4——bean的加载》

根据上面的bean加载过程,一步一步分析:

  • Object sharedInstance = this.getSingleton(beanName);尝试从缓存中读取bean。

    //getSingleton源码
    public Object getSingleton(String beanName) {
        return this.getSingleton(beanName, true);
    }
    
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    
        //检查缓存中是否存在依赖
        Object singletonObject = this.singletonObjects.get(beanName);
        if(singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
            Map var4 = this.singletonObjects;
    
            //如果为空,则锁定全局变量并进行处理。
            synchronized(this.singletonObjects) {
    
                //如果此bean正在加载则不处理。
                singletonObject = this.earlySingletonObjects.get(beanName);
                if(singletonObject == null && allowEarlyReference) {
    
                    //当某些方法需要提前初始化的时候会调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories。
                    ObjectFactory singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                    if(singletonFactory != null) {
    
                        //调用预先设定的getObject方法。
                        singletonObject = singletonFactory.getObject();
    
                        //记录在缓存中,earlySingletonObjects和singletonFactories互斥。
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
    
        return singletonObject != NULL_OBJECT?singletonObject:null;
    }

    解释每个存储bean的map。

    • singletonObjects:用于保存BeanName和创建bean实例间的关系;bean name—>bean instance。
    • singletonFactories:用于保存BeanName和创建bean的工厂之间的关系;bean name—>ObjectFactory。
    • earlySingletonObjects:保存的key/value与singletonObjects一样,与它不同之处在于,当一个单例bean被放到这个容器以后,当bean在创建的过程中,就可以通过getBean方法获取到,其目的是用来检测循环引用。
    • registeredSingletons:用来保存当前所有已注册的bean。
  • getObjectForBeanInstance方法,得到bean的实例后要做的第一步就是调用此方法来检测一下正确性,其实就是用于检测当前bean是否是FactoryBean类型的bean,如果是,就需要调用bean对应的FactoryBean实例中的getObject()作为返回值。

    //getObjectForBeanInstance方法源码
    protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
    
        //如果指定的name是工厂相关(以&为前缀)且beanInstance又不是FactoryBean类型,则验证不通过。
        if(BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
            throw new BeanIsNotAFactoryException(this.transformedBeanName(name), beanInstance.getClass());
        } else if(beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
            Object object = null;
            if(mbd == null) {
    
                //尝试从缓存中加载bean。
                object = this.getCachedObjectForFactoryBean(beanName);
            }
    
            if(object == null) {
                FactoryBean factory = (FactoryBean)beanInstance;
    
                //containsBeanDefinition检测beanDefinitionMap中是否定义beanName,beanDefinitionMap保存的是所有已经加载的类。
                if(mbd == null && this.containsBeanDefinition(beanName)) {
                    mbd = this.getMergedLocalBeanDefinition(beanName);
                }
    
                //是否是用户自定义的而不是程序本身定义的。
                boolean synthetic = mbd != null && mbd.isSynthetic();
    
                //此方法是核心方法。
                object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
            }
    
            return object;
        } else {
            return beanInstance;
        }
    }
    • 上面方法的核心方法:getObjectFromFactoryBean

      //这个方法只做了一件事,就是返回的bean如果是单例的,那就必须要保证全局唯一。
      protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
      
          //如果是单例模式。
          if(factory.isSingleton() && this.containsSingleton(beanName)) {
              synchronized(this.getSingletonMutex()) {
      
                  //使用缓存来提高性能。
                  Object ex = this.factoryBeanObjectCache.get(beanName);
                  if(ex == null) {
      
                      //核心方法
                      ex = this.doGetObjectFromFactoryBean(factory, beanName);
                      Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                      if(alreadyThere != null) {
                          ex = alreadyThere;
                      } else {
                          if(ex != null && shouldPostProcess) {
                              try {
      
                                  //如果已经加载过了就要记录下来便于下次使用。
                                  ex = this.postProcessObjectFromFactoryBean(ex, beanName);
                              } catch (Throwable var9) {
                                  throw new BeanCreationException(beanName, "Post-processing of FactoryBean\'s singleton object failed", var9);
                              }
                          }
      
                          this.factoryBeanObjectCache.put(beanName, ex != null?ex:NULL_OBJECT);
                      }
                  }
      
                  return ex != NULL_OBJECT?ex:null;
              }
          } else {
              Object object = this.doGetObjectFromFactoryBean(factory, beanName);
              if(object != null && shouldPostProcess) {
                  try {
                      object = this.postProcessObjectFromFactoryBean(object, beanName);
                  } catch (Throwable var11) {
                      throw new BeanCreationException(beanName, "Post-processing of FactoryBean\'s object failed", var11);
                  }
              }
      
              return object;
          }
      }
    • 上面方法的核心方法doGetObjectFromFactoryBean方法

      private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, String beanName) throws BeanCreationException {
          Object object;
          try {
              if(System.getSecurityManager() != null) {
                  AccessControlContext ex = this.getAccessControlContext();
      
                  try {
                      object = AccessController.doPrivileged(new PrivilegedExceptionAction() {
                          public Object run() throws Exception {
                              return factory.getObject();
                          }
                      }, ex);
                  } catch (PrivilegedActionException var6) {
                      throw var6.getException();
                  }
              } else {
      
                  //这是重点,终于等到了getObject()
                  object = factory.getObject();
              }
          } catch (FactoryBeanNotInitializedException var7) {
              throw new BeanCurrentlyInCreationException(beanName, var7.toString());
          } catch (Throwable var8) {
              throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", var8);
          }
      
          if(object == null && this.isSingletonCurrentlyInCreation(beanName)) {
              throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");
          } else {
              return object;
          }
      }
  • sharedInstance = this.getSingleton;此方法适用与缓存中不存在已经加载的单例bean,此时就需要从头开始bean的加载,spring定义了不同的getSingleton重载方法实现bean的加载。

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "\'beanName\' must not be null");
        Map var3 = this.singletonObjects;

        //全局变量需要同步。
        synchronized(this.singletonObjects) {

            //首先检查对应的bean是否已经加载过,因为singleton模式其实就是复用已经创建的bean
            Object singletonObject = this.singletonObjects.get(beanName);

            //如果为null才进行singleton的bean初始化。
            if(singletonObject == null) {
                if(this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }

                if(this.logger.isDebugEnabled()) {
                    this.logger.debug("Creating shared instance of singleton bean \'" + beanName + "\'");
                }

                //记录加载状态,将当前正要创建的bean记录在缓存中,这样便可以对循环依赖进行检测。
                this.beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = this.suppressedExceptions == null;
                if(recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet();
                }

                try {

                    //初始化bean
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                } catch (IllegalStateException var16) {
                    singletonObject = this.singletonObjects.get(beanName);
                    if(singletonObject == null) {
                        throw var16;
                    }
                } catch (BeanCreationException var17) {
                    BeanCreationException ex = var17;
                    if(recordSuppressedExceptions) {
                        Iterator var8 = this.suppressedExceptions.iterator();

                        while(var8.hasNext()) {
                            Exception suppressedException = (Exception)var8.next();
                            ex.addRelatedCause(suppressedException);
                        }
                    }

                    throw ex;
                } finally {
                    if(recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }

                    this.afterSingletonCreation(beanName);
                }

                if(newSingleton) {

                    //加入缓存
                    this.addSingleton(beanName, singletonObject);
                }
            }

            return singletonObject != NULL_OBJECT?singletonObject:null;
        }
    }
  • 调用sharedInstance = this.getSingleton时传的第二个参数,ObjectFactory类型的一个匿名内部类,里面有一个非常重要的方法,createBean是真正创建bean的方法。
//创建匿名内部类的源码如下:
 sharedInstance = this.getSingleton(beanName, new ObjectFactory() {
                        public Object getObject() throws BeansException {
                            try {
                                return AbstractBeanFactory.this.createBean(beanName, ex1, args);
                            } catch (BeansException var2) {
                                AbstractBeanFactory.this.destroySingleton(beanName);
                                throw var2;
                            }
                        }
                    });


//createBean的源码。
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
        if(this.logger.isDebugEnabled()) {
            this.logger.debug("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) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        try {
            //验证和准备覆盖的方法,主要是对override属性进行标记和验证。
            //这个函数就是为了lookup-method和replace-method准备的。
            mbdToUse.prepareMethodOverrides();
        } catch (BeanDefinitionValidationException var7) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var7);
        }

        Object beanInstance;
        try {
            beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
            if(beanInstance != null) {
                return beanInstance;
            }
        } catch (Throwable var8) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var8);
        }

        beanInstance = this.doCreateBean(beanName, mbdToUse, args);
        if(this.logger.isDebugEnabled()) {
            this.logger.debug("Finished creating instance of bean \'" + beanName + "\'");
        }

        return beanInstance;
    }
  • 对override属性的处理。上面prepareMethodOverrides

    public void prepareMethodOverrides() throws BeanDefinitionValidationException {
        MethodOverrides methodOverrides = this.getMethodOverrides();
        if(!methodOverrides.isEmpty()) {
            Set overrides = methodOverrides.getOverrides();
            synchronized(overrides) {
                Iterator var4 = overrides.iterator();
    
                while(var4.hasNext()) {
                    MethodOverride mo = (MethodOverride)var4.next();
    
                    //核心方法
                    this.prepareMethodOverride(mo);
                }
            }
        }
    }
    
    
    //prepareMethodOverride方法的源码
    protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
    
        //获取对应类中对应方法名的个数。
        int count = ClassUtils.getMethodCountForName(this.getBeanClass(), mo.getMethodName());
        if(count == 0) {
            throw new BeanDefinitionValidationException("Invalid method override: no method with name \'" + mo.getMethodName() + "\' on class [" + this.getBeanClassName() + "]");
        } else {
            if(count == 1) {
    
                //标记MethodOverride暂未被覆盖,避免参数类型检查的开销。
                mo.setOverloaded(false);
            }
    
        }
    }
    
  • beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse)方法:

    //在调用doCreate方法之前还执行了以下两步。这两步是对BeanDefinition中的属性做些前置处理。spring的AOP就是基于这一步的判断。
        beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
        if(beanInstance != null) {
                return beanInstance;
        }
    
    
    //resolveBeforeInstantiation方法的源码。
    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if(!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            if(!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                Class targetType = this.determineTargetType(beanName, mbd, new Class[0]);
                if(targetType != null) {
    
                    //这是核心方法。
                    bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if(bean != null) {
                        bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
    
            mbd.beforeInstantiationResolved = Boolean.valueOf(bean != null);
        }
    
        return bean;
    }
    
    
    //applyBeanPostProcessorsBeforeInstantiation这个方法是bean实例化的前置处理,源码如下:
    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;
    }
    
    //applyBeanPostProcessorsAfterInstantiation这个方法是bean实例后的处理,源码如下:
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
        Iterator var4 = this.getBeanPostProcessors().iterator();
    
        do {
            if(!var4.hasNext()) {
                return result;
            }
    
            BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
            result = beanProcessor.postProcessAfterInitialization(result, beanName);
        } while(result != null);
    
        return result;
    }
    原文作者:Spring Cloud
    原文地址: https://blog.csdn.net/xyh930929/article/details/79119180
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞