AbstractBeanFactory中有getBean的通用逻辑
//AbstractBeanFactory 中getBean方法第源码 @Override public Object getBean(String name, Object... args) throws BeansException { return doGetBean(name, null, args, false); } 复制代码
核心逻辑在:doGetBean中。
玩笑过后让我们看点实在的。
/** * Return an instance, which may be shared or independent, of the specified bean. * 获得一个实例,可以是共享(原型的),独立(单例的),指定的 * @param name the name of the bean to retrieve * @param requiredType the required type of the bean to retrieve * @param args arguments to use when creating a bean instance * using explicit arguments * (only applied when creating a new instance as opposed to retrieving an existing one) * (仅在创建一个新实例时使用,而不是获取一个已经存在的bean) * @param typeCheckOnly whether the instance is obtained for a type check,not for actual use * 是否仅仅是类型检查 * @return an instance of the bean * @throws BeansException if the bean could not be created */ @SuppressWarnings("unchecked") protected <T> T doGetBean( final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { //1.获取对应的beanName ,BeanFactory去掉&,别名找到对应的BeanName final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. //2. 尝试从缓存中获取单例 Spring会,在Bean未创建完成的情况下,创建Bean的ObjectFactory对象,提早曝光,以方便解决循环依赖。 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { 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实例获取对象,如果是FactoryBean 获取它创建的对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. //3.原型依赖的检查,如果是原型,假设存在循环引用,抛出异常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. // 4.检查bean,是否定义在了BeanFactory中, BeanFactory parentBeanFactory = getParentBeanFactory(); // 如果父BeanFactory不为空&&当前并没有beanDefinitionMap不包含, // 委托给父BeanFactory if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. //委托给,需要参数的 getBean方法 return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // No args -> delegate to standard getBean method. // 委托给标准的getBean方法 return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } if (!typeCheckOnly) { //不仅是,类型检查,标记bean为创建 // 允许bean可以重新合并 markBeanAsCreated(beanName); } try { //5.将GernericBeanDefinition转换为RootBeanDefinition, //如果Bean有父Bean,时会合并父类的相关属性。 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that // the current bean depends on. // 6.保证bean的依赖先初始化了 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { // 对应@DependsOn 注解, /** * 检测是否存在 depends-on 循环依赖,若存在则抛异常。 * 比如 A 依赖 B, * B 又依赖 A,他们的配置如下: @Bean(name="a") @DependsOn("b")public A a () { return new A();} @Bean(name = "b") @DependsOn("a") public B b () { return new B(); } * a 要求 b 在其之前被创建,但 b 又要求 a 先于它 * 创建。这个时候形成了循环,对于 depends-on 循环,Spring 会直接 * 抛出异常 * *@see org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan */ if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } //注册,Dependent和Bean的关系 registerDependentBean(dep, beanName); try { //先创建Dependent getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // Create bean instance. //7.创建Bean的实例 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); 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; } } // Check if required type matches the type of the actual bean instance. // 8.进行类型转换 // requiredType.isInstance(bean) 类似 bean instanceof requiredType // 为true表示可以直接返回,或强转 //clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj) //仅当obj not null 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()); } } return (T) bean; } 复制代码
当看完主流程时,我有如下疑问:
getObjectForBeanInstance和createBean的逻辑下一篇再聊,预计20190921前上传。这里先说下2,4。
简单说,就是清除原有的RootBeanDefinition,再通过当前的多个GenericBeanDefinition合并成新的RootBeanDefinition,供BeanFactory使用。
如果有兴趣可以搜索
org.springframework.beans.factory.config.BeanDefinition org.springframework.beans.factory.support.GenericBeanDefinition org.springframework.beans.factory.support.RootBeanDefinition
我最开始以为是bean需要依赖,处理Autowired注解,然而不是。 利用IDEA查找了调用BeanDefinition的setDependsOn的地方,
发现了AnnotationConfigUtils.processCommonDefinitionAnnotations方法中如如下代码:
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class); if (dependsOn != null) { abd.setDependsOn(dependsOn.getStringArray("value")); } 复制代码
也就是说doGetBean中的
String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { ..... } 复制代码
是对@DependOn注解的支持,我孤陋寡闻,工作中重来没有使用过@DependOn注解。从网上查阅了资料。
当时我查下的资料的url: blog.csdn.net/qq_30257149…
@DependOn注解用来表示一个bean A的实例化依赖另一个bean B的实例化, 但是A并不需要持有一个B的对象