Spring源码阅读
Posted coshaho
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring源码阅读相关的知识,希望对你有一定的参考价值。
我们先看AbstractBeanFactory.getBean方法,这个方法通过bean名称类型等信息获取类实例,如果实例不存在则生产。
//--------------------------------------------------------------------- // Implementation of BeanFactory interface //--------------------------------------------------------------------- @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }
关键方法doGetBean解读如下
/** * Return an instance, which may be shared or independent, of the specified bean. * 返回一个共享或独立实例(单例或者多实例) * @param name the name of the bean to retrieve * bean名称 * @param requiredType the required type of the bean to retrieve * 期望返回的bean类型 * @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) * 实例初始化参数(构造函数参数) * @param typeCheckOnly whether the instance is obtained for a type check, * not for actual use * 标志是否仅仅检查类型 * @return an instance of the bean * 返回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 { // bean名称转换,包括别名转换和&前缀处理(&前缀用于工厂类) final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. // 单例模式下优先使用已经创建的实例,已经在创建中则等待 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean ‘" + beanName + "‘ that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean ‘" + beanName + "‘"); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we‘re already creating this bean instance: // We‘re assumably within a circular reference. // 防止类环形依赖创建时出现死锁 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. // 检查父工厂是否存在这个类实例 BeanFactory parentBeanFactory = getParentBeanFactory(); 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. return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } } // 实例创建前上锁 if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { // 获取bean配置,这里会把配置转化为RootBeanDefinition final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // 检查配置是否为抽象类 checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. // 优先加载依赖类 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between ‘" + beanName + "‘ and ‘" + dep + "‘"); } registerDependentBean(dep, beanName); getBean(dep); } } // Create bean instance. // 创建单例 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; } }); // 1、 如果有其他类依赖此类,需要进行通知 // 2、 如果此类是工厂类,一般需要调用工厂方法返回类实例,而不是直接返回工厂类 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. // 如果传入了类型,则会进行类型转换 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.isDebugEnabled()) { logger.debug("Failed to convert bean ‘" + name + "‘ to required type ‘" + ClassUtils.getQualifiedName(requiredType) + "‘", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
关键代码getSingleton下一讲继续研究。
以上是关于Spring源码阅读的主要内容,如果未能解决你的问题,请参考以下文章
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段
spring源码阅读笔记之HelloWorld和spring第一步ClassPathXMLApplicationContext