阿里面试官:没看过spring源码,简历上竟然敢写精通,早点回家吧!

前言

springmvc,springboot,springcloud以及他们很多配套框架,比如各种stater,springsecurity等所有的基础是spring,作为spring家族的源码分析最基础的部分,这篇文章把spring给大家尽量用最简单的方法,把主要流程讲清楚。为后续的springboot,springcloud,以及其他相关框架分析打下基础。

spring框架简单的例子

引入依赖:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>4.3.11.RELEASE</version>
</dependency>

定义一个接口:

public interface DemoService {    
  String getData();
}

定义接口实现类:

public class DemoServiceImpl implements DemoService {     
  public String getData() {        
    return "hello world";    
  }
}

接下来,我们在 resources 目录新建一个配置文件,文件随意,这里命名成application.xml:

<?xml version="1.0" encoding="UTF-8" ?>
  <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       
  xmlns="http://www.springframework.org/schema/beans"       
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" 
  default-autowire="byName">     
  <bean id="demoService" class="com.wang.example.DemoServiceImpl"/>
</beans>

这样,我们就可以跑起来了:

public class App {    
  public static void main(String[] args) {  
    // 用我们的配置文件来启动一个 ApplicationContext
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");         
    System.out.println("context 启动成功");         
    // 从 context 中取出我们的 Bean,这是spring的方式,不用去new DemoServiceImpl       
    DemoService demoService = context.getBean(demoService.class);        
    // 这句将输出: hello world        
    System.out.println(demoService.getData());   
  }
}

这就是一个最简单使用spring的例子,可能很多直接用springboot开发的人都已经不了解这个了,但是如果想要分析spring源码首先要知道它怎么用,如果不知道怎么用,源码分析就无从谈起了。

接下来以这个例子为入口,一起分析下spring的流程。

分析之前我先简单说下流程,后续验证下spring源码的整体流程是不是这样:

会扫描指定的配置文件“classpath:application.xml”,然后扫描解析xml文件,按照里面的节点信息比如“”,实例化对应的对象,对象信息就是节点定义的信息,最后放入到map集合中,叫做“容器”。
后续“context.getBean(demoService.class)”方法其实就是从容器(前面的map集合)中获取到的实例。
这里的map集合其实就是spring容器,对应spring中FactoryBean这个类,看名字就知道它是管理bean的一个类。

看一下FactoryBean的部分源码:

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";

    Object getBean(String var1) throws BeansException;

    <T> T getBean(String var1, Class<T> var2) throws BeansException;

    Object getBean(String var1, Object... var2) throws BeansException;

    <T> T getBean(Class<T> var1) throws BeansException;

    <T> T getBean(Class<T> var1, Object... var2) throws BeansException;
    ...
}

关注公众号:麒麟改bug,分享一份170多页的spring核心学习笔记。

可以看到它是一个接口,里面定义了获取bean的各种方法,其实就是从map集合中获取的。上面例子中ApplicationContext和FactoryBean什么关系呢?

答案:FactoryBean是ApplicationContext的父类,所以ApplicationContext属于容器

上图是BeanFactory和ApplicationContext类继承关系,以及主要的BeanFactory子类,后续分析会涉及到这张类图,后续说到类图记得回到这里啊。

FileSystemXmlApplicationContext 构造函数需要一个 xml 配置文件在系统中的路径和ClassPathXmlApplicationContext功能差不多,都是扫描xml文件生成实例的容器。

AnnotationConfigApplicationContext 是用于扫描注解生成实例的容器,目前springboot都是用的这个,等到后续分析springboot源码的时候就可以看到了。

知道了类的大体继承关系后,下面开始分析代码:

ClassPathXmlApplicationContext:

public ClassPathXmlApplicationContext(
      String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
      throws BeansException {
   super(parent);
   // 把配置文件的路径设置到ApplicationContext,供后续调用解析使用
   setConfigLocations(configLocations);
   if (refresh) {
      // spring解析的核心方法
      refresh();
   }
}

AbstractApplicationContext

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // 准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符。不是
      // 核心逻辑,知道就行了
      prepareRefresh();

      // 这个是核心逻辑的第一步,
      // 1. new DefaultListableBeanFactory() 这是核心的容器BeanFactory,都是通过它
      //    获取对应的实例对象的
      // 2. loadBeanDefinitions,解析配置文件application.xml中的实例对象,并生成
      //    一个一个的BeanDefinition,放入Map<String, BeanDefinition> 的一个map中,
      //    其中string是bean的名字,BeanDefinition是描述了一个bean类。
      // 这个时候还没有开始实例化的操作,只是把类的信息解析到了BeanDefinition中。
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 做一些准备工作给Beanfactory,其实就是给beanFactory进行了一系列的配置工作,为
      // 后续操作做准备。比如:ClassLoader 和post-processors等
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         // 这里主要提供给子类的一个扩展点,主要是添加BeanPostProcessor,供子类使用,在
         // 后续finishBeanFactoryInitialization方法中完成实例化后会调用
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
         // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         // 后续会在finishBeanFactoryInitialization中触发
         registerBeanPostProcessors(beanFactory);

         // Initialize message source for this context.
         initMessageSource();

         // 初始化 ApplicationContext 的事件广播器,spring中的publicEvent核心方法就是它,
         // 用来发送事件通知的,监听器可以监听到发出的事件,这个在实际工作中是有用到的。
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         // 钩子函数,供子类扩展使用的.
         // --------------------------------------------------------
         // springboot中,就是有子类实现了这个方法,进而创建
         // 出内嵌了tomcat容器,创建了WebServerStartStopLifecycle,供tomcat启动
         // 这块会在我后续文章中说明
         onRefresh();

         // Check for listener beans and register them.
         // 注册各种Listeners,上面initApplicationEventMulticaster方法注册了广播器
         // 最后发出的广播事件,都是被这里的监听器来监听的。
         // --------------------------------------------------------
         // springboot启动的时候,会通它做各种的初始化操作,关注我后面的文章
         registerListeners();

         // 这个是最重要的了,也是核心逻辑实例并初始化所有的singleton beans
         finishBeanFactoryInitialization(beanFactory);

         // 调用LifecycleProcessor的onRefresh()方法,并发送ContextRefreshedEvent事件。
         // 收尾工作了属于。
         // --------------------------------------------------------
         // 对于springboot在上面的onRefresh方法中创建了WebServerStartStopLifecycle,
         // 在这一步会调用WebServerStartStopLifecycle的onRefresh方法,完成springboot内嵌
         // tomcat容器的启动。
         // 后面我会单独开一篇文章来讲springboot源码会提到这块,请关注我。
         finishRefresh();
      }
			....
   }
}

这是主要流程了,里面我都加了注释,和springboot相关的代码我也加了注释。为后续分析springboot源码的文章做准备,希望大家多多关注我后续的文章。

这里只分析spring相关的核心代码:

obtainFreshBeanFactory

finishBeanFactoryInitialization

obtainFreshBeanFactory流程分析

主要完成了创建bean容器,并注册对应的BeanDefinition到容器中

AbstractApplicationContext:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   // 创建新的 BeanFactory,加载 Bean 定义、注册 Bean
   refreshBeanFactory();
   return getBeanFactory();
}

AbstractRefreshableApplicationContext:

protected final void refreshBeanFactory() throws BeansException {
   // 如果已经加载过 BeanFactory了,并销毁BeanFactory中所有 Bean,关闭 BeanFactory
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      // 创建BeanFactory,创建的子类是DefaultListableBeanFactory,为什么用这个子类?
      // 下面说
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());
      // 设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
      customizeBeanFactory(beanFactory);
      // 加载 Bean 到 BeanFactory 中
      loadBeanDefinitions(beanFactory);
      //把容器设置给当前的ApplicationContext
      this.beanFactory = beanFactory;
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

为什么用DefaultListableBeanFactory子类呢?再看下这个类图

DefaultListableBeanFactory几乎继承了所有的BeanFactory相关的类,它把祖祖辈辈的功能都继承下来了,它最牛逼了,所以就创建它了。

前面代码中也提到BeanDefinition,它是spring中很重要的一个类,保存了xml中bean类的定义信息,英文翻译过来也是这个意思“bean定义”,看下它的代码如下:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
   // spring中创建类的方式
   // singleton 只有一个实例,也即是单例模式。
   // prototype访问一次创建一个实例,相当于new。
   String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
   String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
   ...
 
   // 设置父 BeanName
   void setParentName(String parentName);
 
   // 获取父 BeanName
   String getParentName();
 
   // 设置 Bean 的类名称
   void setBeanClassName(String beanClassName);
 
   // 获取 Bean 的类名称
   String getBeanClassName();
 
 
   // 设置 bean 的 scope
   void setScope(String scope);
 
   String getScope();
 
   // 设置是否懒加载
   void setLazyInit(boolean lazyInit);
 
   boolean isLazyInit();
 
   // 设置该 Bean 依赖的所有的 Bean,注意,这里的依赖不是指属性依赖(如 @Autowire 标记的),
   // 是 depends-on="" 属性设置的值。
   void setDependsOn(String... dependsOn);
 
   // 返回该 Bean 的所有依赖
   String[] getDependsOn();
 
   // 设置该 Bean 是否可以注入到其他 Bean 中,只对根据类型注入有效,
   // 如果根据名称注入,即使这边设置了 false,也是可以的
   void setAutowireCandidate(boolean autowireCandidate);
 
   // 该 Bean 是否可以注入到其他 Bean 中
   boolean isAutowireCandidate();
 
   // 主要的。同一接口的多个实现,如果不指定名字的话,Spring 会优先选择设置 primary 为 true 的 bean
   void setPrimary(boolean primary);
 
   // 是否是 primary 的
   boolean isPrimary();
 
   // 如果该 Bean 采用工厂方法生成,指定工厂名称。对工厂不熟悉的读者,请参加附录
   void setFactoryBeanName(String factoryBeanName);
   // 获取工厂名称
   String getFactoryBeanName();
   // 指定工厂类中的 工厂方法名称
   void setFactoryMethodName(String factoryMethodName);
   // 获取工厂类中的 工厂方法名称
   String getFactoryMethodName();
 
   // 构造器参数
   ConstructorArgumentValues getConstructorArgumentValues();
 
   // Bean 中的属性值,后面给 bean 注入属性值的时候会说到
   MutablePropertyValues getPropertyValues();
 
   // 是否 singleton
   boolean isSingleton();
 
   // 是否 prototype
   boolean isPrototype();
 
   // 如果这个 Bean 原生是抽象类,那么不能实例化
   boolean isAbstract();
 
   int getRole();
   String getDescription();
   String getResourceDescription();
   BeanDefinition getOriginatingBeanDefinition();
}

可以看到BeanDefinition定义了bean的所有信息,通过它就能把一个bean实例化出来。

接着分析上面的代码:

主要就是如下两个方法了

customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory)
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
   if (this.allowBeanDefinitionOverriding != null) {
      // 设置是否允许用一个同名的bean name覆盖bean类定义,来替换前面的一个。
      // 如果允许就替换了,如果不允许就会抛个异常。
      // spring中默认是true,允许。
      beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
   }
   if (this.allowCircularReferences != null) {
      // 设置是否允许循环依赖,并自动解决这个问题。默认是true。
      // 循环依赖就是类A依赖B,B里面通过依赖A,这就是循环依赖了。
      // spring解决这个问题,思路就是用单例(好多教程叫缓存,无所谓了),就是第一次
      // A实例化的时候会放到map容器中,因为依赖B,所以会再实例化B去,实例化
      // B的时候发现B又依赖A,所有又去实例化A,这个时候发现A已经在map容器中存在了,
      // 所以就直接返回,这样就不会再继续循环下去了。
      beanFactory.setAllowCircularReferences(this.allowCircularReferences);
   }
}

继续分析loadBeanDefinitions,它是最主要的,解析了xml,并注册了BeanDefinition到容器中。

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
   // 给BeanFactory实例化一个 XmlBeanDefinitionReader,看名字就知道
   // 就是解析xml用的
   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

   // Configure the bean definition reader with this context's
   // resource loading environment.
   beanDefinitionReader.setEnvironment(this.getEnvironment());
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

   // 不重要,跳过
   initBeanDefinitionReader(beanDefinitionReader);
   // 继续跟进它,主线逻辑
   loadBeanDefinitions(beanDefinitionReader);
}

loadBeanDefinitions调用最终会把beanDefinition注册到容器中

调用比较多,这个流程我用时序图画出来。

最后调用了这个方法,把BeanDefinition注册到容器中了。下面列出了核心方法。

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {

      ...
      
   BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
   // 如果已经存在了这个BeanDefinition
   if (existingDefinition != null) {
      // 检查是否允许覆盖
      if (!isAllowBeanDefinitionOverriding()) {
         // 如果不允许覆盖就抛出异常,前面分析过这个属性了
         throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
      }
      // 注册到容器中,这样就覆盖了原来的bean。
      this.beanDefinitionMap.put(beanName, beanDefinition);
   }
   else {
      // 不存在该bean
      if (hasBeanCreationStarted()) {
         //已经开始创建流程了,用锁锁住,避免冲突
         // Cannot modify startup-time collection elements anymore (for stable iteration)
         synchronized (this.beanDefinitionMap) {
            // 放到容器中
            this.beanDefinitionMap.put(beanName, beanDefinition);
            List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
            updatedDefinitions.addAll(this.beanDefinitionNames);
            updatedDefinitions.add(beanName);
            this.beanDefinitionNames = updatedDefinitions;
            removeManualSingletonName(beanName);
         }
      }
      else {
         // 注册beanDefinition到容器中
         this.beanDefinitionMap.put(beanName, beanDefinition);
         this.beanDefinitionNames.add(beanName);
         removeManualSingletonName(beanName);
      }
      this.frozenBeanDefinitionNames = null;
   }
   ...
}

至此,终于把obtainFreshBeanFactory流程讲完了。

接下来继续finishBeanFactoryInitialization核心流程,把类实例化出来,代码如下:

AbstractApplicationContext

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // 实例化名字为 conversionService 的 Bean。
   // 这块挺常用,后面单独说下,beanFactory.getBean这个方法会触发实例化操作。
   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
      beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   }
   ...
 
   // Stop using the temporary ClassLoader for type matching.
   beanFactory.setTempClassLoader(null);
 
   // 冻结beanDefinition信息,这个时候要开始实例化了,不期望再修改这些信息了。
   // 主要就是设置了一个冻结标示
   beanFactory.freezeConfiguration();
 
   // 实例化bean流程
   beanFactory.preInstantiateSingletons();
}

DefaultListableBeanFactory:

@Override
public void preInstantiateSingletons() throws BeansException {
   if (this.logger.isDebugEnabled()) {
      this.logger.debug("Pre-instantiating singletons in " + this);
   }
 
   List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
 
   // 触发所有的非懒加载的singleton beans 的初始化操作
   for (String beanName : beanNames) {
 
      // 合并父 Bean 中的配置,注意 <bean id="" class="" parent="" /> 中的 parent,
      // 后面会有文章专门讲解
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
 
      // 非抽象、非懒加载的 singletons单例。
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         // 处理 FactoryBean,注意FactoryBean和BeanFactory的区别,后面单独
         // 写文章讲解
         if (isFactoryBean(beanName)) {
            // FactoryBean 的话,在 beanName 前面加上 ‘&’ 符号,然后再调用 getBean,
            // getBean方法最核心方法了会实例化bean,因为前面加上了‘&’符号,所以
            // 获取的就是FactoryBean类型的对象了。
            // --------------------------------------------------
            // 这里简单普及下你定义一个类实现了FactoryBean中的getObject方法,getBean的时候
            // 如果名字前加‘&’会获取这个对象本身,比如Demo类实现了FactoryBean,然后你
            // getBean("&demo"),获取的就是Demo本身。
            // --------------------------------------------------
            // 所以源码中的这个getBean会把你实现了FactoryBean
            // 的类实例化,并放到spring容器中。
            // 后续当你在程序中调用getBean(‘demo’),名字中不加的时候‘&’符号,进而
            // 就会发现容器中已经存在了你的实例对象了(比如上面例子中的Demo),
            // 因为这次你没有加“&”符号,流程会有所不同,它会调用demo实例的getObject方法。
            // 当然这里只是把实现了FactoryBean的类实例化,并放入容器了
            final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
            ...
         }
         else {
            // 对于普通的 Bean,只要调用 getBean(beanName) 这个方法就可以进行初始化了
            getBean(beanName);
         }
      }
   }
 
 
   // 到这里说明所有的非懒加载的 singleton beans 已经完成了初始化
   // 如果我们定义的 bean 是实现了 SmartInitializingSingleton 接口的,那么在这里得到回调,忽略
   for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) {
         final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
               @Override
               public Object run() {
                  smartSingleton.afterSingletonsInstantiated();
                  return null;
               }
            }, getAccessControlContext());
         }
         else {
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}

接下来分析getBean,会调用doGetBean方法,分析它:

protected <T> T doGetBean(
      String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
      throws BeansException {

   String beanName = transformedBeanName(name);
   Object bean;

   // 检查对象是否已经实例化过了,如果实例化过了,直接从缓存取出来。
   // 如果没有注册过,这里返回肯定就是null了。里面的涉及到三级缓存(很多文章都这样叫)。
   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,如果是就调用它的getObject方法,
      // 如果不是就直接返回实例。
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
   }

   else {
      ....
      try {
         RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         checkMergedBeanDefinition(mbd, beanName, args);

         // 检查当前bean是否有depends-on相关的配置,如果有就先实例化依赖项。
         // 对应的注解@DependsOn
         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);
               try {
                  getBean(dep);
               }
               catch (NoSuchBeanDefinitionException ex) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
               }
            }
         }

         // 创建单例对象,主要逻辑.
         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 {
           ...省去不重要代码
         }
      }
      catch (BeansException ex) {
         cleanupAfterBeanCreationFailure(beanName);
         throw ex;
      }
   }

   // 如果传入了requiredType,检查requiredType和bean类型是否匹配,它也会尝试转换一下,
   // finishBeanFactoryInitialization方法的最开始有提到conversionService,就是
   // 在这里会尝试做转换,这块平时工作用的也比较多,比如日期格式转换相关的,就是在这里
   // 转换的。
   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;
}

关注公众号:麒麟改bug,分享一份170多页的spring核心学习笔记。

接下来再看createBean方法,它会执行具体的实例化,并把实例化后的对象放到容器中。

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {
   if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
   RootBeanDefinition mbdToUse = mbd;

   // 确保 BeanDefinition 中的 Class 被加载
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }
  // 准备方法覆盖,不重要
   try {
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }

   try {
      // 提供BeanPostProcessors接口一个机会来替换当前bean,来返回你自己定义的代理
      // bean。
      // 对应的方法postProcessBeforeInstantiation和postProcessAfterInstantiation.
      // 方法入参是bean,返回的也是bean,给你机会让你在方法中替换下。
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean;
      }
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }

   try {
      // 创建实例的核心方法
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isTraceEnabled()) {
         logger.trace("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
   }
   catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
      // A previously detected exception with proper bean creation context already,
      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
   }
}

AbstractAutowireCapableBeanFactory:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
      // 实例化对象
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   .....

   // 解决循环依赖问题的
   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
         isSingletonCurrentlyInCreation(beanName));
   if (earlySingletonExposure) {
      if (logger.isTraceEnabled()) {
         logger.trace("Eagerly caching bean '" + beanName +
               "' to allow for resolving potential circular references");
      }
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
   }

   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
      // 处理依赖注入比如@Autowaried,@Resource,实例对象的属性赋值操作。
      populateBean(beanName, mbd, instanceWrapper);
      // 调用各种回调函数。比如BeanPostProcessor接口的回调,
      // InitializingBean接口的afterPropertiesSet的回调接口,以及各种
      // Aware接口。
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
   ....
   
   return exposedObject;
}

这里省去了不必要的代码。

分析到这里大体的情况已经比较清晰了,如果有兴趣可以再深入分析。

这里把initializeBean方法分析下,因为工作中用的比较多。

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      // 调用各Aware子类的接口
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      // 调用BeanPostProcessors接口的postProcessBeforeInitialization方法
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      // 调用InitializingBean接口的afterPropertiesSet方法,各种框架种经常
      // 用来,做一些启动后的初始化工作。
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }
   if (mbd == null || !mbd.isSynthetic()) {
     // 调用BeanPostProcessors接口的postProcessAfterInitialization方法
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

总结

把整体的流程串了一遍,里面也有比较详细的注释。这里面涉及到很多spring给开发者留的口,来让开发者进行扩展回调使用。这些扩展口也是很有用,限于篇幅,我后面会再写一篇文章把这些重要的扩展点配合源码给大家讲明白。

接下来还会跟大家分析springboot,springcloud,mybatis, springAOP等源码分析,spring是基础一定要先看懂这篇文章,可以自己对照着代码,自己跟一遍,这块懂了,后续的分析就都简单了。

喜欢文章记得关注我点赞哟,感谢支持!重要的事情说三遍,转发+转发+转发,一定要记得转发哦!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值