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

 2019-11-23 10:58  阅读(902)
文章分类:Spring Cloud

首先先说一下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加载的时序图:

2019112310056\_1.png

根据上面的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;
        }
    

来源:http://ddrv.cn/a/88268

点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> Spring源码解析笔记4——bean的加载

相关推荐