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放入二级缓存中 |