sping源码解析

1.关于AbstractBeanFactory的内容

AbstractBeanFactory继承FactoryBeanRegistrySupport并且实现了ConfigurableBeanFactory

1.1AbstractBeanFactory中定义的参数

//通过BeanFactory来实现对bean的基础支持
private BeanFactory parentBeanFactory;

ClassLoader:

1. 第一个:

@Nullable //不允许空,对bean名字的解析
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();

2.第二个:

@Nullable//不允许为空,临时解析bean名字时调用
private ClassLoader tempClassLoader;
//通过cacheBeanMetadata这个标值来表示是保存bean的数据到缓存还是每次访问时重新获取,默认为true,当为true时候不需要每次访问时重新获取
private boolean cacheBeanMetadata = true;
//bean中表达式的解析策略
private BeanExpressionResolver beanExpressionResolver;
//spring的转换器
ConversionService
//定制PropertyEditorRegistrars应用于该工厂的bean
private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4);
//定制PropertyEditor应用于该工厂的bean
private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>(4);
//要使用的自定义TypeConverter,将覆盖默认的PropertyEditor机制。
private TypeConverter typeConverter;
//字符解析器,用于解析属性值
private final List<StringValueResolver> embeddedValueResolvers = new CopyOnWriteArrayList<>();
//bean的后置处理器,可以用来批量处理,在bean的初始化之后
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
//指示是否已注册任何bean的后置处理类,默认false
private volatile boolean hasInstantiationAwareBeanPostProcessors;
//指示是否销毁bean的后置处理类,默认false
private volatile boolean hasDestructionAwareBeanPostProcessors;
private final Map<String, Scope> scopes = new LinkedHashMap<>(8);
private SecurityContextProvider securityContextProvider;
//从bean名称映射到合并的根定义bean对象缓存
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
//至少已经创建一次的bean
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
//当前正在创建的bean的名称。
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
      new NamedThreadLocal<>("Prototype beans currently in creation");

1.2AbstractBeanFactory执行的代码

1.执行AbstractBeanFactory构造,创建一个抽象bean的工厂

public AbstractBeanFactory(@Nullable BeanFactory parentBeanFactory) {
   this.parentBeanFactory = parentBeanFactory;
}

2.实现一些BeanFactory的方法,比如获取beangetBean(string name),再在里面调用doGetBean方法

3.doGetBean的方法,返回一个bean的实例

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
​
        final String beanName = transformedBeanName(name);
        Object bean;
​
        // 检查单例缓存中是否有手动注册的缓存实例,不管有没有,都会返回一个单例的共享实例sharedInstance
        Object sharedInstance = getSingleton(beanName);
         //判断单例和参数是否为空
        if (sharedInstance != null && args == null) {
            //判断日志状态,即是否启动跟踪日志记录
            if (logger.isTraceEnabled()) {
          //老生常谈,见下文,从动态创建bean的缓存判断是否工厂范围内正在根据beanName创建bean,这一步目的只是为了记录日志   
        if (isSingletonCurrentlyInCreation(beanName)) {
        logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
        "' that is not fully initialized yet - a consequence of a circular reference");}
        else {
            logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
             }
          }
            //如果上述判断成立(对应的是判断单例和参数是否为空的判断),则证明已经创建好了,就直接获取bean
            //getObjectForBeanInstance()的作用是
            //获取给定的bean实例的对象,不管是在bean实例本身或者其创建的对象在一个FactoryBean的情况
            /**
            *代码如下:
            传的参数分别是:bean的实例,bean可能的前缀名(因为spring可能会忽略前缀),bean的名字
                            bean的根
  protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {}
​
        // 如果Bean不是工厂,则不要让调用代码尝试取消引用工厂
        //说白了就是判断这个是不是工厂bean
        if (BeanFactoryUtils.isFactoryDereference(name)) {
            if (beanInstance instanceof NullBean) {
                return beanInstance;
            }
            if (!(beanInstance instanceof FactoryBean)) {
                throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
            }
            if (mbd != null) {
                mbd.isFactoryBean = true;
            }
            return beanInstance;
        }
​
        // 现在有了一个bean或者是factorybean,可以开始来创建
        if (!(beanInstance instanceof FactoryBean)) {
            return beanInstance;
        }
​
        Object object = null;
        if (mbd != null) {
            mbd.isFactoryBean = true;
        }
        else {
            object = getCachedObjectForFactoryBean(beanName);
        }
        if (object == null) {
            // 返回工厂中匹配的实例
            FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
            // 如果是单例则直接从factorybean缓存中直接获取.
            if (mbd == null && containsBeanDefinition(beanName)) {
            //getMergedLocalBeanDefinition的本质其实就是:
            //  private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
                mbd = getMergedLocalBeanDefinition(beanName);
            }
            boolean synthetic = (mbd != null && mbd.isSynthetic());
            object = getObjectFromFactoryBean(factory, beanName, !synthetic);
        }
        return object;
    }
​
     */
            //正常走到这里就创建成功一个bean了
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
​
        else {
            // 当然如果上述判断的不成立,即(单例不为空或者参数不为空),那么肯定是存在循环引用
            //因此需要对这种情况进行处理
            //是否需要抛出与循环引用对应的异常
            //判断方法:isPrototypeCurrentlyInCreation(),
            //取出当前线程正在创建的bean的名称:
                //private final ThreadLocal<Object> prototypesCurrentlyInCreation =new NamedThreadLocal<>("Prototype beans currently in creation");
            //判断条件:以下三点都要满足
            //  1.当前线程创建不为空  2.当前线程名和beanName一样  3.当前创建的bean和要创建的类型一样
            //满足如上三点即抛出循环引用配套的异常,因为此时相当于自己引用自己
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }
​
            // 检查是否bean已经在工厂中定义
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // 如果工厂存在,但是没有包含beanName对应的定义信息,检查上一级
                String nameToLookup = originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                }
                else if (args != null) {
                    // 使用显式参数委派给父级。
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else if (requiredType != null) {
                    //如果没有参数,则委派方法给父级
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
                else {
                    return (T) parentBeanFactory.getBean(nameToLookup);
                }
            }
            //是否获取实例以进行类型检查,,一般传入默认为false,即不开启
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }
            //下述一块代码主要是为了依赖注入的方面
            //主要使用到isDependent方法,然后再通过checkMergedBeanDefinition检查,                          通过registerDependentBean注入
            try {
                //遍历beanName的所有定义,并存储起来
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                //检查定义是否存在冲突
                checkMergedBeanDefinition(mbd, beanName, args);
​
                // 取出当前bean所有依赖的 保障bean的初始化。
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                for (String dep : dependsOn) {
                //isDependent是判断当前beanName是否已经被注册或者为依赖其他bean所依赖引用
                 //isDependent方法中用到
                //private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
                //从bean的依赖存储的map中取出依赖,具体见下文,如果有重复依赖,则报错
                    if (isDependent(beanName, dep)) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                    //给指定的bean注入他所有的依赖,并且在指定的bean被销毁之前销毁
                        registerDependentBean(dep, beanName);
                        try {
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }
​
                //创建bean的实例
                //当要创建的bean为单例时
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            //遍历factorybean工厂
                            //解决循环依赖的重要方法
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                //如果有异常时
                //从单例缓存中显式删除实例:它可能已经放在那里
                //急于通过创建过程,以允许循环引用解析。
                //还删除所有收到对bean的临时引用的bean。
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                //创建bean的实例
                //当要创建的bean为多例时
                else if (mbd.isPrototype()) {
                    //创建新实例
                    Object prototypeInstance = null;
                    try {
                        //创建原型时先调用,规定要创建的原型,其实就是将beanName加入一个set中
                        //并且在当前线程中添加beanName
  //private final ThreadLocal<Object> prototypesCurrentlyInCreation = new NamedThreadLocal<>("Prototype beans currently in creation");
                        beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        //创建原型后调用
                        //在当前线程中移除beanName,再在之前的set中把beanName删掉哦
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }
​
                else {
                    //获取bean的作用域名称
                    String scopeName = mbd.getScope();
                    //从scope中获取scopeName对应的scope
                    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, () -> {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                afterPrototypeCreation(beanName);
                            }
                        });
                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    }
                    catch (IllegalStateException ex) {
                        throw new BeanCreationException(beanName,
                                "Scope '" + scopeName + "' 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",
                                ex);
                    }
                }
            }
            catch (BeansException ex) {
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }
​
        // 检查创建出来的实例是否时要求的实例
        if (requiredType != null && !requiredType.isInstance(bean)) {
            try {
                T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                if (convertedBean == null) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
                return convertedBean;
            }
            catch (TypeMismatchException ex) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
    //返回bean
        return (T) bean;
    }
​
//doGetBean中调用DefaultSingletonBeanRegistry的getSingleton方法,获取单例实例
public Object getSingleton(String beanName) {
   return getSingleton(beanName, true);
}
//getSingleton获取实例
    @Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        //this.singletonObjects中的singletonObjects是DefaultSingletonBeanRegistry声明的一个单例对象和名字相对应的告诉缓存
       //声明代码:  
       //private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
        Object singletonObject = this.singletonObjects.get(beanName);
        //isSingletonCurrentlyInCreation()这个方法是用来判断是否这个beanName还是处于生产的工厂范围中,即判断是否已经构建完成
       /** 
       方法如下:
       public boolean isSingletonCurrentlyInCreation(String beanName) {
        return this.singletonsCurrentlyInCreation.contains(beanName);
        }
    */
      //其中this.singletonsCurrentlyInCreation也是一个缓存,他是指当前正在创建bean的缓存,那么为啥能用上述isSingletonCurrentlyInCreation()方法判断是否构建完成呢,因为调用了map的contain方法判断是否当前正在创建bean的缓存中是否有这个bean,如果没有,则创建完成
        /**DefaultSingletonBeanRegistry中的this.singletonsCurrentlyInCreation代码如下:
        *   
            private final Set<String> inCreationCheckExclusions =
                        Collections.newSetFromMap(new ConcurrentHashMap<>(16));
        */
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            //上锁
            synchronized (this.singletonObjects) {
             // 早期的单例对象的高速缓存this.earlySingletonObjects
             //private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
             //上述earlySingletonObjects常量也是在DefaultSingletonBeanRegistry申明
                singletonObject = this.earlySingletonObjects.get(beanName);
                //如果早期单例对象的高速缓存没有,则进行创建,至于allowEarlyReference在getSingleton()方法中已经赋值为true.所以关键在于是否早期单例对象缓存是否有对象
                if (singletonObject == null && allowEarlyReference) {
        //this.singletonFactories又是一个工厂缓存,判断工厂缓存中是否有beanName对应的工厂构造
       //代码如下:
      //private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
    //为什么这里不判断为空呢?个人理解是因为spring交给工厂构造,所以你的beanName工厂中必有,所以如果没有,只能是构造完成了,这也是为什么要判断一次不等于null,因为防止并发情况下,由于单例,众所周知,单例懒汉式存在线程不安全,因此这次判断不等于null可以隔绝这个清空,不等于null那之前那些缓存中就已经存在了
                    if (singletonFactory != null) {
                        //由对应工厂进行构造
                        singletonObject = singletonFactory.getObject();
                        //放入早期构造的单例缓存中
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        //从对应工厂中移除
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
    //alreadySeen当调用isDependent()的重载时候默认为空
   if (alreadySeen != null && alreadySeen.contains(beanName)) {
      return false;
   }
    //获取依赖的原始名称
   String canonicalName = canonicalName(beanName);
    //从对应bean的存储的所有的依赖集合中取出进行匹配
   Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
   if (dependentBeans == null) {
      return false;
   }
   if (dependentBeans.contains(dependentBeanName)) {
       //当为true的时候,doGetBean会报错
       //为true的时候,也是循环依赖的一种,我个人理解为循环使用,如A使用了之前使用过的依赖
      return true;
   }
   for (String transitiveDependency : dependentBeans) {
      if (alreadySeen == null) {
         alreadySeen = new HashSet<>();
      }
       //将每次的依赖都进行存储进去
      alreadySeen.add(beanName);
      if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
         return true;
      }
   }
   return false;
}

1.3.spring三级缓存:其实位置感觉就是在DefaultSingletonBeanRegistry,而且感觉就是基于JVM的,用map或者说ConcurrentHashMap来实现的

缓存说明
singleObjects第一级缓存,放成品,直接可以使用的构建完成的,放入ConcurrentHashMap中
earlySingletonObjects第二级缓存,放入较早的半成品,即这时候的bean只是刚new完,但是没有依赖注入(注入属性和初始化),这样才能解决循环依赖
singletonFactories第三级缓存,存放的是Bean的工厂对象,用来可以通过beanName来创建半成品的bean放入二级缓存中
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值