Spring源码分析 Bean创建和获取

    xiaoxiao2022-07-07  207

    Spring源码分析 Bean创建和获取

    Spring获取Bean源码

    public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } protected Object doGetBean(String name, Class requiredType, final Object args[], boolean typeCheckOnly) throws BeansException { final String beanName; Object bean; final RootBeanDefinition mbd; Object prototypeInstance; beanName = transformedBeanName(name); // 先尝试从缓存中获取bean,对于那些单例模式的Bean,缓存获取 Object sharedInstance = getSingleton(beanName); if(sharedInstance != null && args == null) { if(logger.isDebugEnabled()) if(isSingletonCurrentlyInCreation(beanName)) logger.debug((new StringBuilder()).append("Returning eagerly cached instance of singleton bean '").append(beanName).append("' that is not fully initialized yet - a consequence of a circular reference").toString()); else logger.debug((new StringBuilder()).append("Returning cached instance of singleton bean '").append(beanName).append("'").toString()); bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); break MISSING_BLOCK_LABEL_544; } if(isPrototypeCurrentlyInCreation(beanName)) throw new BeanCurrentlyInCreationException(beanName); BeanFactory parentBeanFactory = getParentBeanFactory(); if(parentBeanFactory != null && !containsBeanDefinition(beanName)) { String nameToLookup = originalBeanName(name); if(args != null) return parentBeanFactory.getBean(nameToLookup, args); else return parentBeanFactory.getBean(nameToLookup, requiredType); } if(!typeCheckOnly) markBeanAsCreated(beanName); mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); String dependsOn[] = mbd.getDependsOn(); if(dependsOn != null) { String arr$[] = dependsOn; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { String dependsOnBean = arr$[i$]; getBean(dependsOnBean); registerDependentBean(dependsOnBean, beanName); } } if(mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory() { public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch(BeansException ex) { destroySingleton(beanName); throw ex; } } final String val$beanName; final RootBeanDefinition val$mbd; final Object val$args[]; final AbstractBeanFactory this$0; { this$0 = AbstractBeanFactory.this; beanName = s; mbd = rootbeandefinition; args = aobj; super(); } } ); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); break MISSING_BLOCK_LABEL_544; } if(!mbd.isPrototype()) break MISSING_BLOCK_LABEL_399; prototypeInstance = null; beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); afterPrototypeCreation(beanName); break MISSING_BLOCK_LABEL_383; Exception exception; exception; afterPrototypeCreation(beanName); throw exception; bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); break MISSING_BLOCK_LABEL_544; String scopeName = mbd.getScope(); Scope scope = (Scope)scopes.get(scopeName); if(scope == null) throw new IllegalStateException((new StringBuilder()).append("No Scope registered for scope '").append(scopeName).append("'").toString()); try { Object scopedInstance = scope.get(beanName, new ObjectFactory() { public Object getObject() throws BeansException { beforePrototypeCreation(beanName); Object obj = createBean(beanName, mbd, args); afterPrototypeCreation(beanName); return obj; Exception exception1; exception1; afterPrototypeCreation(beanName); throw exception1; } final String val$beanName; final RootBeanDefinition val$mbd; final Object val$args[]; final AbstractBeanFactory this$0; { this$0 = AbstractBeanFactory.this; beanName = s; mbd = rootbeandefinition; args = aobj; super(); } } ); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch(IllegalStateException ex) { throw new BeanCreationException(beanName, (new StringBuilder()).append("Scope '").append(scopeName).append("' is not active for the current thread; ").append("consider defining a scoped proxy for this bean if you intend to refer to it from a singleton").toString(), ex); } if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { try { return getTypeConverter().convertIfNecessary(bean, requiredType); } catch(TypeMismatchException ex) { if(logger.isDebugEnabled()) logger.debug((new StringBuilder()).append("Failed to convert bean '").append(name).append("' to required type [").append(ClassUtils.getQualifiedName(requiredType)).append("]").toString(), ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } else { return bean; } }

    如图所示,源码分析 首先获取bean的名称 beanName = transformedBeanName(name); 然后查看缓存中bean是否存在,如下图

    Object sharedInstance = getSingleton(beanName); private final Map singletonObjects = new ConcurrentHashMap(64); private final Map alreadyCreated; protected Object getSingleton(String beanName, boolean allowEarlyReference) { /*1*/ Object singletonObject = singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) synchronized (singletonObjects) { singletonObject = earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory singletonFactory = (ObjectFactory) singletonFactories .get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); earlySingletonObjects.put(beanName, singletonObject); singletonFactories.remove(beanName); } } } return singletonObject == NULL_OBJECT ? null : singletonObject; } /*2*/ protected void markBeanAsCreated(String beanName) { alreadyCreated.put(beanName, Boolean.TRUE); } /*3*/ String dependsOn[] = mbd.getDependsOn(); if(dependsOn != null) { String arr$[] = dependsOn; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { String dependsOnBean = arr$[i$]; getBean(dependsOnBean); registerDependentBean(dependsOnBean, beanName); } }

    紧接着,如图1 通过singletonObjects缓存对象去获取对象,由于可见,Spring底层用的缓存大多数是缓存在Map结构中,缓存对象首次初始化的时候为空,构建之前会先调用 如图2-markBeanAsCreated()标明此处bean状态为构建中, 继续分析如下 如图3 后续会查看当前bean是否有依赖引用,如A依赖B,首先会把B创建成功后,然后注入到A中 下叙真实获取bean对象源码

    public static transient Object instantiateClass(Constructor ctor, Object args[]) throws BeanInstantiationException { Assert.notNull(ctor, "Constructor must not be null"); try { ReflectionUtils.makeAccessible(ctor); return ctor.newInstance(args); } catch (InstantiationException ex) { throw new BeanInstantiationException(ctor.getDeclaringClass(), "Is it an abstract class?", ex); } catch (IllegalAccessException ex) { throw new BeanInstantiationException(ctor.getDeclaringClass(), "Is the constructor accessible?", ex); } catch (IllegalArgumentException ex) { throw new BeanInstantiationException(ctor.getDeclaringClass(), "Illegal arguments for constructor", ex); } catch (InvocationTargetException ex) { throw new BeanInstantiationException(ctor.getDeclaringClass(), "Constructor threw exception", ex.getTargetException()); } } public static void makeAccessible(Constructor ctor) { if ((!Modifier.isPublic(ctor.getModifiers()) || !Modifier.isPublic(ctor .getDeclaringClass().getModifiers())) && !ctor.isAccessible()) ctor.setAccessible(true); }

    由此得出结论,bean创建实例是通过java反射来实现,创建之前会检查访问修饰类型,如果不是public可见的,调用setAccessible(true);得到私有构造方法来构建对象实例,接下来要把bean中默认设置的属性值注入,创建出来的单例bean对象添加到缓存中,供下次直接使用,到此bean创建和获取流程结束

    protected void addSingleton(String beanName, Object singletonObject) { synchronized (singletonObjects) { //Map缓存单例bean对象 singletonObjects.put(beanName, singletonObject == null ? NULL_OBJECT : singletonObject); singletonFactories.remove(beanName); earlySingletonObjects.remove(beanName); registeredSingletons.add(beanName); } }

    总结:

    SpringBean创建和获取

    Spring的bean实际上是缓存在CurrentHashMap对象中创建bean之前,首先要将该bean的创建标识设定好,表示该bean已经即将被创建,其目的增强缓存效率根据bean的Scope属性来确定是singleton还是prototype等范围,然后创建相应bean对象通过java反射创建bean的实例接下来,寻找bean的属性值,完成属性注入将所创建出来的singleton对象添加到缓存中,供下次调用使用

    作者简介:张程 技术研究

    更多文章请关注微信公众号:zachary分解狮 (frankly0423)

    最新回复(0)