Spring Ioc源码解析

目录

目录.png

一.spring模块

spring模块.png
  • 底层core container就是ioc容器,其中beans主要是BeanFactory低级容器,context 其中ApplicationContext是高级容器,通过组合的形式依赖BeanFactory低级容器。core是一些StringUtils之类的通用类
  • AOP面向切面编程
  • Web springMvc之类的
  • Data Access 中orm框架比如mybatis
    ....................................................................................................................................................

二. 项目中使用的地方

  • 采用拓展版的SpringMvc + Spring + 自定义orm框架
  • 项目实现了ServletContextListener(servlet这块代码不文不涉及),其中启动时会调用如下代码
// ioc容器启动
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(springConfigLocation);
// 存起来,后续springmvc处理url时会调用getBean。
ServletContext.INSTANCE.setApplicationContext(applicationContext);
  • applicationContent配置中配置了自动扫描bean

....................................................................................................................................................

三.spring ioc启动流程

  • 注意: 如果对spring一点基础都没有,请google下基本使用
1. 从ClassPathXmlApplicationContext开始分析
  • ClassPathXmlApplicationContext是根据 xml 文件内容来构建 ApplicationContext
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(springConfigLocation);
2. ClassPathXmlApplicationContext继续关系
  • 盗用参考文章1的简化版继续关系图


    ClassPathXmlApplicationContext继续关系.png
  • 其中AbstractRefreshableApplicationContext持有DefaultListableBeanFactory beanFactory引用,也就是与低级容器组合,ApplicationContext高级容器提供更多更高级功能。
  • DefaultListableBeanFactory 顾名思义就是持有多个bean的list,其中持有多个BeanDefinition ,BeanDefinition 中保存了我们的 Bean 信息,比如这个 Bean 指向的是哪个类、是否是单例的、是否懒加载、这个 Bean 依赖了哪些 Bean 等等。


    DefaultListableBeanFactory 关系图.png
3.ioc启动过程分析
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
      throws BeansException {
 
    super(parent);
    // 根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割)
    setConfigLocations(configLocations);
    if (refresh) {
      // 核心方法
      refresh(); 
    }
}
4. refresh核心方法
  • refresh是在ClassPathXmlApplicationContext父类AbstractApplicationContext实现
// 不叫Init就是因为你可以refresh刷新下
@Override
public void refresh() throws BeansException, IllegalStateException {
   // 防止refresh还没结束,你又启动容器
   synchronized (this.startupShutdownMonitor) {
 
      // 步骤1. 准备工作,记录下容器的启动时间、处理配置文件中的占位符
      prepareRefresh();
 
      /**
      * 步骤2. 将各个需要spring管理的bean通过BeanDefinition形式 注册到DefaultListableBeanFactory中,
      * 说到底核心是一个 beanName-> beanDefinition 的 map,
      * 项目定义了spring自动扫描bean,spring会将需要扫描的包底下
      * 有@Component,@Service, @Controller等这些注解的扫描到注册到DefaultListableBeanFactory中
      **/

      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 
      // 步骤3. 设置 BeanFactory 的类加载器,添加几个特殊的BeanPostProcessor,保证了这些需要先添加的顺序性链表结构
      prepareBeanFactory(beanFactory);
 
      try {
        
        
        /**
        * 步骤4. 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
        * 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
        **/
         postProcessBeanFactory(beanFactory);
         //步骤 5. 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法, 占位符解析就在这里。
         invokeBeanFactoryPostProcessors(beanFactory);
 
         /**
         * 步骤6. 注册 BeanPostProcessor 的实现类包括aop的后置处理器也是在这里注册的,注意看和 BeanFactoryPostProcessor 的区别
         * 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         * 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
         **/
         registerBeanPostProcessors(beanFactory);
 
         // 步骤7. 初始化当前 ApplicationContext 的 MessageSource,国际化
         initMessageSource();
 
         // 步骤8. 初始化当前 ApplicationContext 的事件广播器
         initApplicationEventMulticaster();
 
         // 步骤9. 从方法名就可以知道,典型的模板方法(钩子方法),供拓展
         onRefresh();
 
         // 步骤10. 注册事件监听器,监听器需要实现 ApplicationListener 接口。
         registerListeners();
 
       
         // 步骤11. 初始化除懒加载外所有的单例beans,原型bean不会被报错到ioc容器,比较核心的代码
         finishBeanFactoryInitialization(beanFactory);
 
         // 步骤12. 最后,广播事件,ApplicationContext 初始化完成
         finishRefresh();
      }
 
      catch (BeansException ex) {
         // 异常处理省略
      }
 
      finally {
         // 省略
      }
    }
}

5. 步骤1 prepareRefresh解析
  • 这块比较简单就是些准备工作,记录下容器的启动时间、处理配置文件中的占位符
6. 步骤2 obtainFreshBeanFactory解析
  • 初始化 BeanFactory(ioc容器)、加载 Bean、注册 Bean 等等。
  • 看下AbstractApplicationContext.obtainFreshBeanFactory方法
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   // 创建新的 BeanFactory,加载 Bean 定义、注册 Bean 等等
   refreshBeanFactory();
 
   // 返回刚刚创建的 BeanFactory (省略部分Log代码)
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   return beanFactory;
}
  • 继续看AbstractRefreshableApplicationContext.refreshBeanFactory方法
protected final void refreshBeanFactory() throws BeansException {
    
   // 省略部分代码
   try {
      // 初始化一个 DefaultListableBeanFactory
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());
      // 设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
      customizeBeanFactory(beanFactory);
 
      // 核心方法,加载 Bean 到 BeanFactory 中
      loadBeanDefinitions(beanFactory);
      synchronized (this.beanFactoryMonitor) {
         this.beanFactory = beanFactory;
      }
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}
  • 继续看重要方法AbstractXmlApplicationContext.loadBeanDefinitions
//此方法将通过一个 XmlBeanDefinitionReader 实例来加载各个 Bean
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
   // 给这个 BeanFactory 实例化一个 XmlBeanDefinitionReader
   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

   beanDefinitionReader.setEnvironment(this.getEnvironment());
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
 
   // 重要方法
   loadBeanDefinitions(beanDefinitionReader);
   
}

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
   // 关注loadBeanDefinitions方法
   String[] configLocations = getConfigLocations();
   if (configLocations != null) {
      reader.loadBeanDefinitions(configLocations);
   }
}

  • 继续看AbstractBeanDefinitionReader.loadBeanDefinitions方法
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
    // 这里我们只传一个location, classpath:applicationContext.xml
    int counter = 0;
    for (String location : locations) {
        counter += loadBeanDefinitions(location);
    }
    return counter;
}

public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
        return loadBeanDefinitions(location, null);
    }
  • 继续看XmlBeanDefinitionReader.loadBeanDefinitions方法
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
    return loadBeanDefinitions(new EncodedResource(resource));
}

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    // 省略部分代码
    try {
        // 读取文件
        InputStream inputStream = encodedResource.getResource().getInputStream();
        try {
            InputSource inputSource = new InputSource(inputStream);
            if (encodedResource.getEncoding() != null) {
                inputSource.setEncoding(encodedResource.getEncoding());
            }
            // 重点关注
            return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
        }
        finally {
            inputStream.close();
        }
    }
    // 省略部分代码
}


protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
      throws BeanDefinitionStoreException {
   try {
      // xml文件解析成Document,org.w3c.dom里面的
      Document doc = doLoadDocument(inputSource, resource);
      // 重点关注
      return registerBeanDefinitions(doc, resource);
   }
   catch (...


// 返回从当前配置文件加载了多少数量的 Bean
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
   BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
   int countBefore = getRegistry().getBeanDefinitionCount();
   // 重点关注
   documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
   return getRegistry().getBeanDefinitionCount() - countBefore;

  • 继续看DefaultBeanDefinitionDocumentReader.registerBeanDefinitions

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
   Element root = doc.getDocumentElement();
   // 重点关注
   doRegisterBeanDefinitions(root);
}
  • 这里一个配置文件终于转换为一颗 DOM 树了,继续看DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions方法
protected void doRegisterBeanDefinitions(Element root) {
   /**
   * 我们看名字就知道,BeanDefinitionParserDelegate 必定是一个重要的类,它负责解析 Bean 定义,
   * 这里为什么要定义一个 parent? 看到后面就知道了,是递归问题
   * 因为  内部是可以定义  的,所以这个方法的 root 其实不一定就是 xml 的根节点,也可以是嵌套在里面的  节点,从源码分析的角度,我们当做根节点就好了
   **/
   BeanDefinitionParserDelegate parent = this.delegate;
   this.delegate = createDelegate(getReaderContext(), root, parent);
 
   if (this.delegate.isDefaultNamespace(root)) {
       /**
        * 这块说的是根节点  中的 profile 是否是当前环境需要的,
        * 如果当前环境配置的 profile 不包含此 profile,那就直接 return 了,不对此  解析
       **/
      String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
      if (StringUtils.hasText(profileSpec)) {
         String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
               profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
         if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
            if (logger.isInfoEnabled()) {
               logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
                     "] not matching: " + getReaderContext().getResource());
            }
            return;
         }
      }
   }
 
   preProcessXml(root); // 钩子
   // 重要方法
   parseBeanDefinitions(root, this.delegate);
   postProcessXml(root); // 钩子
 
   this.delegate = parent;
}


// default namespace 涉及到的就四个标签 ,
// 其他的属于 custom 的
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
   if (delegate.isDefaultNamespace(root)) {
      NodeList nl = root.getChildNodes();
      for (int i = 0; i < nl.getLength(); i++) {
         Node node = nl.item(i);
         if (node instanceof Element) {
            Element ele = (Element) node;
            if (delegate.isDefaultNamespace(ele)) {
               parseDefaultElement(ele, delegate);
            }
            else {
               delegate.parseCustomElement(ele);
            }
         }
      }
   }
   else {
      // 我们这里要解析context:component-scan,所以直接看这个方法
      delegate.parseCustomElement(root);
   }
}
  • 继续看BeanDefinitionParserDelegate.parseCustomElement方法
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
    String namespaceUri = getNamespaceURI(ele);
    NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
    if (handler == null) {
        error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
        return null;
    }
    // 因为这里要解析标签context:component-scan,所以是ContextNamespaceHandler处理
    return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}

// ContextNamespaceHandler父类NamespaceHandlerSupport处理
public BeanDefinition parse(Element element, ParserContext parserContext) {
        // 重点关注parse方法
    return findParserForElement(element, parserContext).parse(element, parserContext);
}

  • 调用ComponentScanBeanDefinitionParser.parse方法
public BeanDefinition parse(Element element, ParserContext parserContext) {
    String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
    basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
    String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
            ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);

    ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
    // 扫描basePackage包将所有含有@Component,@Service等几个注解的类扫描出来
    // 通过BeanDefinition形式注册所有需要注册的bean到ioc容器
    Set beanDefinitions = scanner.doScan(basePackages);
    
    
    registerComponents(parserContext.getReaderContext(), beanDefinitions, element);

    return null;
}
  • 看下扫描的逻辑ClassPathBeanDefinitionScanner.doScan,这里面有扫描出来的bean放到ioc容器的操作
protected Set doScan(String... basePackages) {
    // 这里我们只传了一个basePackage
    Set beanDefinitions = new LinkedHashSet();
    for (String basePackage : basePackages) {
        Set candidates = findCandidateComponents(basePackage);
        // 对扫描出来的bean进行注册到ioc容器处理
        for (BeanDefinition candidate : candidates) {
            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
            candidate.setScope(scopeMetadata.getScopeName());
            String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
            if (candidate instanceof AbstractBeanDefinition) {
                postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
            }
            if (candidate instanceof AnnotatedBeanDefinition) {
                AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
            }
            if (checkCandidate(beanName, candidate)) {
                BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                beanDefinitions.add(definitionHolder);
                // 注册到ioc容器
                registerBeanDefinition(definitionHolder, this.registry);
            }
        }
    }
    return beanDefinitions;
}

// 看下注册到ioc那块代码
protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}

//BeanDefinitionReaderUtils.registerBeanDefinition
public static void registerBeanDefinition(
        BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
        throws BeanDefinitionStoreException {

    // 重要代码
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    //省略部分代码
}

// 实际处理是放到DefaultListableBeanFactory的beanDefinitionMap 里面
private final Map beanDefinitionMap = new ConcurrentHashMap(256);
  • 到这里已经初始化了ioc 容器, 配置也相应的转换为了一个个 BeanDefinition,然后注册了各个 BeanDefinition 到ioc容器
7. 准备 Bean 容器: prepareBeanFactory

-Spring 对一些特殊的 bean 进行了处理

  • 添加几个特殊的BeanPostProcessor,保证了这些需要先添加的顺序性链表结构
  • 比如EmbeddedValueResolverAware,ApplicationContextAware
8. 第四第五点
  • BeanFactoryPostProcessor是接触BeanDefinintion,可以在bean初始化化之前修改BeanDefinition。常见的PropertyPlaceholderConfigurer
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
  • 注意 FactoryBean是在getBean中实现的
9.第六点
  • 盗图参考文章第六点图, BeanPostProcessor注册作用


    BeanPostProcessor.png
  • 注意图中的InstantiationAwareBeanPostProcessor是BeanPostProcessor的子类,其中的postProcessBeforeInstantiation和postProcessAfterInstantiation都重载了,所以spring总体调用
  • InitializingBean,FactoryBean, Aware, InstantiationAwareBeanPostProcessor解析
  1. InitializingBean源码: 初始化阶段一个个bean时会判断是否属于 InitializingBean,属于则回调
  2. SmartFactoryBean源码(继承自FactoryBean, 区别是前者启动时会注入ioc容器,后者第一次调用才会): 实现FactoryBean的接口不走正常的实例化,属性赋值,初始化流程,走refresh中preInstantiateSingletons另一个分支,如果isEagerInit设置为true那么启动时就初始化了。
  3. ApplicationContextAware源码:aware接口实现如EmbeddedValueResolverAware,ApplicationContextAware这些都是在实例化阶段调用postProcessBeforeInstantiation,set进行。初始化阶段会判断bean是否属于ApplicationContextAware,是则回调
  4. 自定义BeanPostProcessor源码: 在refresh的registerBeanPostProcessors方法中,会获取前面obtainFreshBeanFactory方法中获取到所有beanDefiniton的BeanPostProcessors类,拿出来注册到beanPostProcessors。然后在初始化阶段调用所有注册的BeanPostProcessors。
  5. InstantiationAwareBeanPostProcessor属于实例化的时候调用,这个aop会使用,分析aop的时候可以学习。
  6. 注意像这些postProcessor是每个类都会调用postProcessBeforeInstantiation,postProcessAfternstantiation方法的,像第四个是aop在使用,调用时会判断是否需要aop拦截生成代理类,不需要则跳过。上述3,4,5每个类初始化的都会调用对应postProcess方法,但是不属于对应的需要拦截的类都会跳过,像aop的AbstractAutoProxyCreator一样不属于需要aop拦截的都会过滤掉。aop中postProcessBeforeInstantiation(Class beanClass, String beanName)是在实例化前调用,目的是先遍历所有bean, 找出@AspectJ类,把其中的增强器封装成Advisor加入list中。postProcessAfterInitialization(@Nullable Object bean, String beanName)是在初始化后调用的,目的是如果需要代理则返回代理类。


    postProcessor
10. 初始化所有的 singleton beans
  • 重点分析finishBeanFactoryInitialization方法,这里会负责初始化所有的 singleton beans。先是类A调用默认构造函数进行默认初始化,再是将各个属性赋值,如果对属性赋值过程中涉及别的类B初始化会重复这个过程,这时候因为持有类B的引用所以初始化真正完成。
  • 看代码部分AbstractApplicationContext类下refresh 方法
// 初始化剩余的 singleton beans
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory){
    // 省略部分代码

    // 开始初始化剩下的   beanFactory.preInstantiateSingletons();
}
  • DefaultListableBeanFactory. preInstantiateSingletons方法
public void preInstantiateSingletons() throws BeansException {
        //省略部分代码

        // 触发所有的非懒加载的 singleton beans 的初始化操作
        for (String beanName : beanNames) {

            // 非抽象、非懒加载的 singletons。如果配置了 'abstract = true',那是不需要初始化的
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                // 处理 FactoryBean
                if (isFactoryBean(beanName)) {
                    
                    if (isEagerInit) {
                        // 正常是走getBean
                        getBean(beanName);
                    }
                }
                else {
                    // 对于普通的 Bean,只要调用 getBean(beanName) 这个方法就可以进行初始化了
                    getBean(beanName);
                }
            }
        }
    }
  • 继续看AbstractBeanFactory. getBean
@Override
    public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null, false);
    }

    // 我们在剖析初始化 Bean 的过程,但是 getBean 方法我们经常是用来从容器中获取 Bean 用的
    @SuppressWarnings("unchecked")
    protected  T doGetBean(
            final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
            throws BeansException {
      
        // 如果 args 不为空的时候,那么意味着调用方不是希望获取 Bean,而是创建 Bean
        if (sharedInstance != null && args == null) {
            // 下面这个方法:如果是普通 Bean 的话,直接返回 sharedInstance
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
        // 这里走else分支,因为这里是要分析创建bean
        else {

            /*
             * 到这里的话,要准备创建 Bean 了,对于 singleton 的 Bean 来说,容器中还没创建过此 Bean;
             * 对于 prototype 的 Bean 来说,本来就是要创建一个新的 Bean。
             */
            try {
                // 先初始化依赖的所有 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);
                    }
                }

                // 创建 singleton 的实例
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, new ObjectFactory() {
                        @Override
                        public Object getObject() throws BeansException {
                            try {
                                // 执行创建 Bean,重要方法
                                return createBean(beanName, mbd, args);
                            }
                            catch (BeansException ex) {
                                destroySingleton(beanName);
                                throw ex;
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

                // 创建 prototype 的实例
                else if (mbd.isPrototype()) {
                    // 省略
                }

                // 如果不是 singleton 和 prototype 的话,需要委托给相应的实现类来处理
                else {
                    
                }
            }
            
        }

        // 最后,检查一下类型对不对,不对的话就抛异常,对的话就返回了
        if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
            
        }
        return (T) bean;
    }

 
 
  • 接下来当然是分析 createBean 方法,AbstractAutowireCapableBeanFactory类里面的,专门针对@Autowire
 protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {  
     // 省略部分代码                                                                                                       
                                                                                                                     
     // 确保 BeanDefinition 中的 Class 被加载                                                                               
     Class resolvedClass = resolveBeanClass(mbd, beanName);                                                       
     if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {                           
     }                                                                                                               
     // 重头戏,创建 bean                                                                                                  
     Object beanInstance = doCreateBean(beanName, mbdToUse, args);                                                   
     return beanInstance;                                                                                            
 }                                                                                                                   
                                                                                                                     
  • 接下来看doCreateBean方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)                
      throws BeanCreationException {                                                                                   
                                                                                                                       
    // 省略部分代码                                                                                                          
                                                                                                                       
    BeanWrapper instanceWrapper = null;                                                                                
                                                                                                                       
    // 这里只是调用默认构造函数进行实例化,属性还没有赋值                                                                                       
    if (instanceWrapper == null) {                                                                                     
        instanceWrapper = createBeanInstance(beanName, mbd, args);                                                     
    }                                                                                                                  
                                                                                                                       
                                                                                                                       
    Object exposedObject = bean;                                                                                       
    try {                                                                                                              
        // 这一步也是非常关键的,这一步负责属性装配,因为前面的实例只是实例化了,属性并没有设值,这里就是设值                                                           
        populateBean(beanName, mbd, instanceWrapper);                                                                  
        if (exposedObject != null) {                                                                                   
            // 还记得 init-method 吗?还有 InitializingBean 接口?还有 BeanPostProcessor 接口?                                       
            // 这里就是处理 bean 初始化完成后的各种回调                                                                                 
            exposedObject = initializeBean(beanName, exposedObject, mbd);                                              
        }                                                                                                              
    }                                                                                                                  
}                                                                                                                      
  • 接下来重点看下createBeanInstance,populateBean,initializeBean方法(调用spring xml中的init 方法,调用initlizible中afterProperty方法), 先看下createBeanInstance
//省略部分代码                                                                                                
                                                                                                        
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {      
   //省略部分代码                                                                                             
                                                                                                        
   // 确保已经加载了此 class                                                                                    
   Class beanClass = resolveBeanClass(mbd, beanName);                                                
                                                                                                        
  //是否第一次                                                                                               
   boolean resolved = false;                                                                            
  //是否采用构造函数注入                                                                                          
   boolean autowireNecessary = false;                                                                   
   if (args == null) {                                                                                  
      synchronized (mbd.constructorArgumentLock) {                                                      
         if (mbd.resolvedConstructorOrFactoryMethod != null) {                                          
            resolved = true;                                                                            
            autowireNecessary = mbd.constructorArgumentsResolved;                                       
         }                                                                                              
      }                                                                                                 
   }                                                                                                    
   if (resolved) {                                                                                      
      if (autowireNecessary) {                                                                          
         return autowireConstructor(beanName, mbd, null, null);                                         
      }                                                                                                 
      else {                                                                                            
         // 无参构造函数                                                                                      
         return instantiateBean(beanName, mbd);                                                         
      }                                                                                                 
   }                                                                                                    
                                                                                                        
   // 判断是否采用有参构造函数                                                                                      
   Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);           
   if (ctors != null ||                                                                                 
         mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||                    
         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {                           
      // 构造函数依赖注入                                                                                       
      return autowireConstructor(beanName, mbd, ctors, args);                                           
   }                                                                                                    
                                                                                                        
   // 调用无参构造函数                                                                                          
   return instantiateBean(beanName, mbd);                                                               
}                                                                                                       

  • 选一个无参的构造看一下instantiateBean
 // 省略部分代码                                                                                                             
 protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {                          
    try {                                                                                                              
       Object beanInstance;                                                                                            
       final BeanFactory parent = this;                                                                                
       if (System.getSecurityManager() != null) {                                                                      
          beanInstance = AccessController.doPrivileged(new PrivilegedAction() {                                
             @Override                                                                                                 
             public Object run() {                                                                                     
                                                                                                                       
                return getInstantiationStrategy().instantiate(mbd, beanName, parent);                                  
             }                                                                                                         
          }, getAccessControlContext());                                                                               
       }                                                                                                               
       else {                                                                                                          
          // 重点方法,具体实例化的实现,往下看                                                                                         
          beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);                                
       }                                                                                                               
       BeanWrapper bw = new BeanWrapperImpl(beanInstance);                                                             
       initBeanWrapper(bw);                                                                                            
       return bw;                                                                                                      
    }                                                                                                                  
    catch (Throwable ex) {                                                                                             
       throw new BeanCreationException(                                                                                
             mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);                              
    }                                                                                                                  
 }                                                                                                                     
                                                                                                                       
                                                                                                                       
 public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {                                
                                                                                                                       
    // 如果不存在方法覆写,那就使用 java 反射进行实例化,否则使用 CGLIB,                                                                         
    if (bd.getMethodOverrides().isEmpty()) {                                                                           
       Constructor constructorToUse;                                                                                
       synchronized (bd.constructorArgumentLock) {                                                                     
          constructorToUse = (Constructor) bd.resolvedConstructorOrFactoryMethod;                                   
          if (constructorToUse == null) {                                                                              
             final Class clazz = bd.getBeanClass();                                                                 
             if (clazz.isInterface()) {                                                                                
                throw new BeanInstantiationException(clazz, "Specified class is an interface");                        
             }                                                                                                         
             try {                                                                                                     
                if (System.getSecurityManager() != null) {                                                             
                   constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction>() {  
                      @Override                                                                                        
                      public Constructor run() throws Exception {                                                   
                         return clazz.getDeclaredConstructor((Class[]) null);                                          
                      }                                                                                                
                   });                                                                                                 
                }                                                                                                      
                else {                                                                                                 
                   constructorToUse = clazz.getDeclaredConstructor((Class[]) null);                                    
                }                                                                                                      
                bd.resolvedConstructorOrFactoryMethod = constructorToUse;                                              
             }                                                                                                         
             catch (Throwable ex) {                                                                                    
                throw new BeanInstantiationException(clazz, "No default constructor found", ex);                       
             }                                                                                                         
          }                                                                                                            
       }                                                                                                               
       // 利用构造方法进行实例化,反射实例化,这里只是调用默认构造函数,属性并没有赋值                                                                       
       return BeanUtils.instantiateClass(constructorToUse);                                                            
    }                                                                                                                  
    else {                                                                                                             
       // 存在方法覆写,利用 CGLIB 来完成实例化,需要依赖于 CGLIB 生成子类,这里就不展开了                                                              
       return instantiateWithMethodInjection(bd, beanName, owner);                                                     
    }                                                                                                                  
 }                                                                                                                     

 
 
  • bean属性注入populateBean (), 重点如果属性是跟别的类B组那么这里会调用类B的初始化,并且持有类B的引用,当类B初始化完成时,类A也完成了属性注入了。
// 省略部分代码                                                                                                    
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {                       
   // bean的所有属性                                                                                              
   PropertyValues pvs = mbd.getPropertyValues();                                                             
                                                                                                             
                                                                                                             
   boolean continueWithPropertyPopulation = true;                                                            
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {                                    
      for (BeanPostProcessor bp : getBeanPostProcessors()) {                                                 
         if (bp instanceof InstantiationAwareBeanPostProcessor) {                                            
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;              
            // 如果返回 false,代表不需要进行后续的属性设值,也不需要再经过其他的 BeanPostProcessor 的处理                                    
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {                     
               continueWithPropertyPopulation = false;                                                       
               break;                                                                                        
            }                                                                                                
         }                                                                                                   
      }                                                                                                      
   }                                                                                                         
                                                                                                             
   if (!continueWithPropertyPopulation) {                                                                    
      return;                                                                                                
   }                                                                                                         
                                                                                                             
   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();                                     
   boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);           
                                                                                                             
   if (hasInstAwareBpps || needsDepCheck) {                                                                  
      PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);  
      if (hasInstAwareBpps) {                                                                                
         for (BeanPostProcessor bp : getBeanPostProcessors()) {                                              
            if (bp instanceof InstantiationAwareBeanPostProcessor) {                                         
               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;           
               // 这里就是上方曾经提到过得对@Autowired处理的一个BeanPostProcessor了                                             
               // 它会对所有标记@Autowired、@Value 注解的属性进行设值                                                         
               pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);     
               if (pvs == null) {                                                                            
                  return;                                                                                    
               }                                                                                             
            }                                                                                                
         }                                                                                                   
      }                                                                                                      
      if (needsDepCheck) {                                                                                   
         checkDependencies(beanName, mbd, filteredPds, pvs);                                                 
      }                                                                                                      
   }                                                                                                         
   // 设置 bean 实例的属性值                                                                                         
   applyPropertyValues(beanName, mbd, bw, pvs);                                                              
}                                                                                                            
                                                                                                             
  • 最终都初始化完成之后,会放到ioc容器councurrent map缓存(DefaultSingletonBeanRegistry.singleObject, key是名称,value是实例对象)

单例getBean

  • 本质上是从councurrent map缓存获取(DefaultSingletonBeanRegistry.singleObject, key是名称,value是实例对象)

循环依赖

  • 三种循环依赖:
  1. 构造器的循环依赖:这种依赖spring是处理不了的,this .singletonsCurrentlylnCreation.add(beanName)将当前正要创建的bean 记录在缓存中
    Spring 容器将每一个正在创建的bean 标识符放在一个“当前创建bean 池”中, bean 标识
    :在创建过程中将一直保持在这个池中,因此如果在创建bean 过程中发现自己已经在“当前
    创建bean 池” 里时,将抛出BeanCurrentlylnCreationException 异常表示循环依赖。
  2. 单例模式下的setter循环依赖:通过“三级缓存”处理循环依赖。
  3. 非单例循环依赖:对于“prototype”作用域bean无法处理,spirng没有缓存非单例的bean。
  • 单例模式下bean:使用三级缓存
  1. singletonFactories : 进入实例化阶段的单例对象工厂的cache (三级缓存)
  2. earlySingletonObjects :完成实例化但是尚未初始化的,提前暴光的单例对象的Cache (二级缓存)
  3. singletonObjects:完成初始化的单例对象的cache(一级缓存)
  • 分析一下“A的某个field或者setter依赖了B的实例对象,同时B的某个field或者setter依赖了A的实例对象”这种循环依赖的情况。A首先完成了初始化的第一步,并且将自己提前曝光到singletonFactories中,此时进行初始化的第二步,发现自己依赖对象B,此时就尝试去get(B),发现B还没有被create,所以走create流程,B在初始化第一步的时候发现自己依赖了对象A,于是尝试get(A),尝试一级缓存singletonObjects(肯定没有,因为A还没初始化完全),尝试二级缓存earlySingletonObjects(也没有),尝试三级缓存singletonFactories,由于A通过ObjectFactory将自己提前曝光了,所以B能够通过ObjectFactory.getObject拿到A对象(虽然A还没有初始化完全,但是总比没有好呀),B拿到A对象后顺利完成了初始化阶段1、2、3,完全初始化之后将自己放入到一级缓存singletonObjects中。此时返回A中,A此时能拿到B的对象顺利完成自己的初始化阶段2、3,最终A也完成了初始化,进去了一级缓存singletonObjects中,而且更加幸运的是,由于B拿到了A的对象引用,所以B现在hold住的A对象完成了初始化。

占位符替换PropertyPlaceholderConfigurer解析

  
         
         
  


  
         
             classpath:/application.properties  
         
  


  • 步骤 5. 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 中解析的
  • 最终会调用PlaceholderConfigurerSupport的doProcessProperties(),这个方法就会取出BeanFactory中的BeanDefinition,然后循环处理除了本身以外的bean的占位符替换

设计模式

建造者模式
  • BeanDefinitionBuilder创建BeanDefinition
工厂方法
  • 在Spring中,我们可以通过指定的工厂方法创建bean

    

代理模式
  • spring aop就是用的代理模式,比如jdk动态代理,cglib代理
策略模式
  • 策略定义了通过不同方式完成相同事情的几个对象。完成任务的方式取决于采用的策略。
  • 作为Spring中的每个控制器,MultiActionController(已经过时)执行方法来响应提供的请求。策略用于检测应使用哪种方法。解析过程在MethodNameResolver实现中实现,例如在同一个包中的ParameterMethodNameResolver中。方法可以通过多个条件解决:属性映射,HTTP请求参数或URL路径。
模版方法
  • 此模式定义了类行为的骨架,并将子步骤的某些步骤的延迟执行
  • refresh方法就是个模版方法
原型模式
  • bean作用域的文章中介绍了类似的概念(prototype)
  • 此设计模式允许通过复制已存在的对象来创建一个对象的实例
public class PrototypeTest {

  @Test
  public void test() {
    Robot firstRobot = new Robot("Droid#1");
    Robot secondRobot = (Robot) firstRobot.clone();
    assertTrue("Cloned robot's instance can't be the same as the"
      +" source robot instance",
      firstRobot != secondRobot);
    assertTrue("Cloned robot's name should be '"+firstRobot.getName()+"'"
      +" but was '"+secondRobot.getName()+"'",
      secondRobot.getName().equals(firstRobot.getName()));
  }

}


class Robot implements Cloneable {
  private String name;

  public Robot(String name) {
    this.name = name;
  }

  public String getName() {
    return this.name;
  }

  protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
}
观察者模式
  • 将应用程序的上下文事件分派给适当的监听器的观察者
  • spring发布订阅模式,可以找个例子实际看看,网上比较多,不展开
单例模式
  • 这种比较多,不展开
适配器
  • springmvc使用适配器模式把不同Handler适配在一起统一对外提供功能
装饰器
  • mybatis提供的二级缓存就是用装饰器,装饰一级缓存,对外提供功能
命令模式
  • 它允许将请求封装在一个对象内并附加一个回调动作(每次遇到所所谓的回调大家就只需要理解为一个函数方法就好,省的去浪费那么多脑子)。请求被封装在命令对象之下,而请求的结果被发送到接收者。命令本身不是由调用者执行。
  • 类似于输入linux命令最终都是由终端执行。客户端输入命令。
  • 实践: 我们将多个方法最终执行某个底层方法
  • spring中:
    我要BeanFactory里面得到对象(也就是为了得到一个命令的执行结果),那么,想要在得到对象的时候就已经实现了一些对其修改的想法,那么就通过后置处理器,也是就实现了后置处理器接口的beans(命令里可以通过传入不同的参数来得到不同结果,或者对命令的脚本进行修改),然后还需要一个执行者(我们在做自动化运维的时候,不止操作一个脚本,这里的PostProcessorRegistrationDelegate就是集中来管理这些的),最后得到的结果就由BeanFactory来展示咯
访问者模式
  • 抽象一点就是通过另一种类型的对象来使一个对象访问,需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,使用访问者模式将这些封装到类中。
  • 可参考 访问者模式

....................................................................................................................................................

参考文章

  1. 最详细的Spring核心IOC的源码分析
  2. 【一叶知秋】Spring 源码解析五个spring用到的设计模式
  3. 面试问烂的 Spring IOC 过程,里面getBean分析还可以
  4. SpringIOC源码解析(上)
  5. SpringIOC源码解析(下)
  6. 别再问Spring Bean的生命周期了!
  7. spring是如何解决循环依赖的
  8. Spring自定义占位符替换(PropertyPlaceholderConfigurer解析)

你可能感兴趣的:(Spring Ioc源码解析)