Spring源码分析

Spring IOC容器初始化主体流程

Spring IOC 的容器体系

IOC容器是Spring的核心模块,是抽象了对象管理、依赖关系管理的框架解决方案。SPring提供了很多的容器,其中BeanFactory是顶层容器(根容器),不能被实例化,它定义了所有IOC容器必须遵从的一套原则,具体的容器实现可以增加额外的功能,比如我们常用到的ApplicationContext,其下更具体的实现如ClassPathXmlApplicationContext包含了解析xml等一系列的内容,

AnnotationConfigApplicationContext则是包含了注解解析等一系列的内容。Spring IOC容器继承体系非常聪明,需要使用哪个层次哪个层次即可,不必使用功能大而全的。

BeanFactory 顶级接⼝⽅法栈如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EHmlE5YB-1619436705001)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210418155821533.png)]

BeanFactory 容器继承体系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CERHe1Go-1619436705004)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210418160004277.png)]

通过其接口设计,我们可以看到我们一贯使用的ApplicationContext除了继承BeanFactory的子接口,还继承了ResourceLoader、MessageSource等接口,因此其提供了功能也就更丰富了。

下面我们以AnnotationConfigApplicationContext为例,深入源码说明IOC容器的初始化流程。

Bean⽣命周期关键时机点

public class SpringTest {
    @Test
    public void testIoC() {
        AnnotationConfigApplicationContext applicationContext = new
                AnnotationConfigApplicationContext(MyAppConfig.class);
       LagouBean lagouBean = applicationContext.getBean(com.yc.LagouBean.class);
        System.out.println(lagouBean);
    }
}

我们在这里打断点会

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZJ45SmkH-1619436705005)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210418162402396.png)]

会进入到一个方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f5ryopuy-1619436705007)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210418162414580.png)]

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
   this();			//调用构造函数
   register(annotatedClasses);			//注册Bean
   refresh();						//创建刷新
}

一直打断点调试会进入到一个方法

public void register(Class<?>... annotatedClasses) {
   for (Class<?> annotatedClass : annotatedClasses) {
      registerBean(annotatedClass);		//根据AppConfig配置类来注册bean
   }
}

因此我们进入registerBean方法一探究竟

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
      @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

   AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);	//根据注解信息注册beanDefinition
    //判断是否要应该跳过
   if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
      return;
   }
	
   abd.setInstanceSupplier(instanceSupplier);
   ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    //设置作用域
   abd.setScope(scopeMetadata.getScopeName());
   String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

   AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
   if (qualifiers != null) {
      for (Class<? extends Annotation> qualifier : qualifiers) {
         if (Primary.class == qualifier) {
            abd.setPrimary(true);
         }
         else if (Lazy.class == qualifier) {
            abd.setLazyInit(true);
         }
         else {
            abd.addQualifier(new AutowireCandidateQualifier(qualifier));
         }
      }
   }
   for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
      customizer.customize(abd);
   }
//得到BeanDefinition的持有,同时持有的包括BeanDefinition的名称和别名
   BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    
   definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    //通过BeanDefinitionHolder来注册BeanDefinition
   BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

进入BeanDefinitionReaderUtils.registerBeanDefinition方法

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

   // Register bean definition under primary name.
   //在主名称下注册bean定义。
   String beanName = definitionHolder.getBeanName();
   registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

   // Register aliases for bean name, if any.
   String[] aliases = definitionHolder.getAliases();
   if (aliases != null) {
      for (String alias : aliases) {
         registry.registerAlias(beanName, alias);
      }
   }
}

这里就是注册BeanDefinition

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {
	//断言验证!
   Assert.hasText(beanName, "Bean name must not be empty");
   Assert.notNull(beanDefinition, "BeanDefinition must not be null");

   if (beanDefinition instanceof AbstractBeanDefinition) {
      try {
          //校验BeanDefinition信息
         ((AbstractBeanDefinition) beanDefinition).validate();
      }
      catch (BeanDefinitionValidationException ex) {
         throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
               "Validation of bean definition failed", ex);
      }
   }
	//看到这里,发现BeanDefinition由一个Map所装,由实例工厂来将BeanDefinitionMap来初始化
    //这里面装着,Spring托管的所有类的定义信息
   BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    //判断能不能从工厂里面得到BeanDefinition如果没有就开始初始化BeanDefinition扫描
   if (existingDefinition != null) {
      if (!isAllowBeanDefinitionOverriding()) {
         throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
      }
      else if (existingDefinition.getRole() < beanDefinition.getRole()) {
         // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
         if (logger.isInfoEnabled()) {
            logger.info("Overriding user-defined bean definition for bean '" + beanName +
                  "' with a framework-generated bean definition: replacing [" +
                  existingDefinition + "] with [" + beanDefinition + "]");
         }
      }
      else if (!beanDefinition.equals(existingDefinition)) {
         if (logger.isDebugEnabled()) {
            logger.debug("Overriding bean definition for bean '" + beanName +
                  "' with a different definition: replacing [" + existingDefinition +
                  "] with [" + beanDefinition + "]");
         }
      }
      else {
         if (logger.isTraceEnabled()) {
            logger.trace("Overriding bean definition for bean '" + beanName +
                  "' with an equivalent definition: replacing [" + existingDefinition +
                  "] with [" + beanDefinition + "]");
         }
      }
      this.beanDefinitionMap.put(beanName, beanDefinition);
   }
   else {
      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 {
         // Still in startup registration phase
         this.beanDefinitionMap.put(beanName, beanDefinition);
         this.beanDefinitionNames.add(beanName);
         removeManualSingletonName(beanName);
      }
      this.frozenBeanDefinitionNames = null;
   }

   if (existingDefinition != null || containsSingleton(beanName)) {
      resetBeanDefinition(beanName);
   }
   else if (isConfigurationFrozen()) {
      clearByTypeCache();
   }
}

fresh方法

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            //刷新前的预处理;
            prepareRefresh();

            //获取BeanFactory;默认实现是DefaultListableBeanFactory,在创建容器的时候创建的
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            //BeanFactory的预准备工作(BeanFactory进行一些设置,比如context的类加载器,BeanPostProcessor和XXXAware自动装配等)
            prepareBeanFactory(beanFactory);

            try {
                //BeanFactory准备工作完成后进行的后置处理工作
                postProcessBeanFactory(beanFactory);

                //执行BeanFactoryPostProcessor的方法;
                invokeBeanFactoryPostProcessors(beanFactory);

                //注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执行
                registerBeanPostProcessors(beanFactory);

                //初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
                initMessageSource();

                //初始化事件派发器
                initApplicationEventMulticaster();

                //子类重写这个方法,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器
                onRefresh();

                //注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的
                registerListeners();

                //初始化所有剩下的非懒加载的单例bean
                finishBeanFactoryInitialization(beanFactory);

                //完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件(ContextRefreshedEvent)
                finishRefresh();
            }

            ......
    }

由上分析可知,Spring IoC 容器初始化的关键环节就在 AbstractApplicationContext#refresh() ⽅法中

,我们查看 refresh ⽅法来俯瞰容器创建的主体流程,主体流程下的具体⼦流程我们后⾯再来讨论。

@Override
public void refresh() throws BeansException, IllegalStateException {
 synchronized (this.startupShutdownMonitor) {
 // 第⼀步:刷新前的预处理
 prepareRefresh();
 /*
 第⼆步:
 获取BeanFactory;默认实现是DefaultListableBeanFactory
 加载BeanDefition 并注册到 BeanDefitionRegistry
 */
 ConfigurableListableBeanFactory beanFactory =
obtainFreshBeanFactory();
 // 第三步:BeanFactory的预准备⼯作(BeanFactory进⾏⼀些设置,⽐如context的类加
载器等)
 prepareBeanFactory(beanFactory);
 try {
 // 第四步:BeanFactory准备⼯作完成后进⾏的后置处理⼯作
 postProcessBeanFactory(beanFactory);
 // 第五步:实例化并调⽤实现了BeanFactoryPostProcessor接⼝的Bean
 invokeBeanFactoryPostProcessors(beanFactory);
 // 第六步:注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执registerBeanPostProcessors(beanFactory);
 // 第七步:初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
 initMessageSource();
 // 第⼋步:初始化事件派发器
 initApplicationEventMulticaster();
 // 第九步:⼦类重写这个⽅法,在容器刷新的时候可以⾃定义逻辑
 onRefresh();
 // 第⼗步:注册应⽤的监听器。就是注册实现了ApplicationListener接⼝的监听器
bean
 registerListeners();
 /*
 第⼗⼀步:
 初始化所有剩下的⾮懒加载的单例bean
 初始化创建⾮懒加载⽅式的单例Bean实例(未设置属性)
 填充属性
 初始化⽅法调⽤(⽐如调⽤afterPropertiesSet⽅法、init-method⽅法)
 调⽤BeanPostProcessor(后置处理器)对实例bean进⾏后置处
 */
 finishBeanFactoryInitialization(beanFactory);
 /*
 第⼗⼆步:
 完成context的刷新。主要是调⽤LifecycleProcessor的onRefresh()⽅法,并且发布事
件 (ContextRefreshedEvent)
 */
 finishRefresh();
 }	
 }
}

BeanFactory创建流程

获取BeanFactory子流程

时序图如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h6Vy9mID-1619436705008)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210418201137880.png)]

BeanDefinition加载解析及注册子流程

(1)该子流程涉及到如下几个关键步骤

**Resource定位:**指对BeanDefinition的资源定位过程。通俗讲就是找到定义JavaBean信息的XML文件,并将其封装成Resource对象。

**BeanDefinition载入:**把用户定义好的JavaBean表示为IOC容器内部的数据结构,这个容器内部的数据结果就是BeanDefinition。

注册BeanDefinition到IOC容器

(2)过程分析

Step 1:子流程入口在AbstractRefreshableApplicationContext#refreshBeanFactory方法中

	@Override
	protected final void refreshBeanFactory() throws BeansException {
		//如果已经有容器,销毁容器中的bean,关闭容器
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			//创建IOC容器
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			//对IOC容器进行定制化,如设置启动参数,开启注解的自动装配等
			customizeBeanFactory(beanFactory);
			//调用载入Bean定义的方法,主要这里又使用了一个委派模式,在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器
			loadBeanDefinitions(beanFactory);		//切入点
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

将loadBeanDefinition作为切点,进入AnnotationConfigWebApplicationContext

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
   //为容器设置注解Bean定义读取器
   AnnotatedBeanDefinitionReader reader = getAnnotatedBeanDefinitionReader(beanFactory);
   //为容器设置类路径Bean定义扫描器
   ClassPathBeanDefinitionScanner scanner = getClassPathBeanDefinitionScanner(beanFactory);

   //获取容器的Bean名称生成器
   BeanNameGenerator beanNameGenerator = getBeanNameGenerator();
   //为注解Bean定义读取器和类路径扫描器设置Bean名称生成器
   if (beanNameGenerator != null) {
      reader.setBeanNameGenerator(beanNameGenerator);
      scanner.setBeanNameGenerator(beanNameGenerator);
      beanFactory.registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);	//注册单例Bean
   }

   //获取容器的作用域元信息解析器
   ScopeMetadataResolver scopeMetadataResolver = getScopeMetadataResolver();
   //为注解Bean定义读取器和类路径扫描器设置作用域元信息解析器
   if (scopeMetadataResolver != null) {
      reader.setScopeMetadataResolver(scopeMetadataResolver);
      scanner.setScopeMetadataResolver(scopeMetadataResolver);
   }

   if (!this.annotatedClasses.isEmpty()) {
      if (logger.isInfoEnabled()) {
         logger.info("Registering annotated classes: [" +
               StringUtils.collectionToCommaDelimitedString(this.annotatedClasses) + "]");
      }
      reader.register(this.annotatedClasses.toArray(new Class<?>[this.annotatedClasses.size()]));
   }

   if (!this.basePackages.isEmpty()) {
      if (logger.isInfoEnabled()) {
         logger.info("Scanning base packages: [" +
               StringUtils.collectionToCommaDelimitedString(this.basePackages) + "]");
      }
      scanner.scan(this.basePackages.toArray(new String[this.basePackages.size()]));
   }

   //获取容器定义的Bean定义资源路径
   String[] configLocations = getConfigLocations();
   //如果定位的Bean定义资源路径不为空
   if (configLocations != null) {
      for (String configLocation : configLocations) {
         try {
            //使用当前容器的类加载器加载定位路径的字节码类文件
            Class<?> clazz = ClassUtils.forName(configLocation, getClassLoader());
            if (logger.isInfoEnabled()) {
               logger.info("Successfully resolved class for [" + configLocation + "]");
            }
            reader.register(clazz);		//重点,进入这里看,将reader(Bean定reader)进行注册
         }
         catch (ClassNotFoundException ex) {
            if (logger.isDebugEnabled()) {
               logger.debug("Could not load class for config location [" + configLocation +
                     "] - trying package scan. " + ex);
            }
            //如果容器类加载器加载定义路径的Bean定义资源失败
            //则启用容器类路径扫描器扫描给定路径包及其子包中的类
            int count = scanner.scan(configLocation);
            if (logger.isInfoEnabled()) {
               if (count == 0) {
                  logger.info("No annotated classes found for specified class/package [" + configLocation + "]");
               }
               else {
                  logger.info("Found " + count + " annotated classes in package [" + configLocation + "]");
               }
            }
         }
      }
   }
}

进入reader.register

//注册多个注解Bean定义类
public void register(Class<?>... annotatedClasses) {
   for (Class<?> annotatedClass : annotatedClasses) {
      registerBean(annotatedClass);
   }
}
//注册一个注解Bean定义类
public void registerBean(Class<?> annotatedClass) {
   doRegisterBean(annotatedClass, null, null, null);
}
//Bean定义读取器向容器注册注解Bean定义类
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
      @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

   //根据指定的注解Bean定义类,创建Spring容器中对注解Bean的封装的数据结构
   AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
   if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
      return;
   }

   abd.setInstanceSupplier(instanceSupplier);
   //解析注解Bean定义的作用域,若@Scope("prototype"),则Bean为原型类型;
   //若@Scope("singleton"),则Bean为单态类型
   ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
   //为注解Bean定义设置作用域
   abd.setScope(scopeMetadata.getScopeName());
   //为注解Bean定义生成Bean名称
   String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

   //处理注解Bean定义中的通用注解
   AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
   //如果在向容器注册注解Bean定义时,使用了额外的限定符注解,则解析限定符注解。
   //主要是配置的关于autowiring自动依赖注入装配的限定条件,即@Qualifier注解
   //Spring自动依赖注入装配默认是按类型装配,如果使用@Qualifier则按名称
   if (qualifiers != null) {
      for (Class<? extends Annotation> qualifier : qualifiers) {
         //如果配置了@Primary注解,设置该Bean为autowiring自动依赖注入装//配时的首选
         if (Primary.class == qualifier) {
            abd.setPrimary(true);
         }
         //如果配置了@Lazy注解,则设置该Bean为非延迟初始化,如果没有配置,
         //则该Bean为预实例化
         else if (Lazy.class == qualifier) {
            abd.setLazyInit(true);
         }
         //如果使用了除@Primary和@Lazy以外的其他注解,则为该Bean添加一
         //个autowiring自动依赖注入装配限定符,该Bean在进autowiring
         //自动依赖注入装配时,根据名称装配限定符指定的Bean
         else {
            abd.addQualifier(new AutowireCandidateQualifier(qualifier));
         }
      }
   }
   for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
      customizer.customize(abd);
   }

   //创建一个指定Bean名称的Bean定义对象,封装注解Bean定义类数据
   BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
   //根据注解Bean定义类中配置的作用域,创建相应的代理对象
   definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
   //向IOC容器注册注解Bean类定义对象
   BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ja1KHfHj-1619436705010)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210418212323760.png)]

//将解析的BeanDefinitionHold注册到容器中
public static void registerBeanDefinition(
      BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
      throws BeanDefinitionStoreException {

   // Register bean definition under primary name.
   //获取解析的BeanDefinition的名称
   String beanName = definitionHolder.getBeanName();
   //向IOC容器注册BeanDefinition
   registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

   // Register aliases for bean name, if any.
   //如果解析的BeanDefinition有别名,向容器为其注册别名
   String[] aliases = definitionHolder.getAliases();
   if (aliases != null) {
      for (String alias : aliases) {
         registry.registerAlias(beanName, alias);
      }
   }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JXdMlh3o-1619436705011)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210418212423082.png)]


registerBeanDefinition方法

//向IOC容器注册解析的BeanDefiniton
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {

   Assert.hasText(beanName, "Bean name must not be empty");
   Assert.notNull(beanDefinition, "BeanDefinition must not be null");

   //校验解析的BeanDefiniton
   if (beanDefinition instanceof AbstractBeanDefinition) {
      try {
         ((AbstractBeanDefinition) beanDefinition).validate();
      }
      catch (BeanDefinitionValidationException ex) {
         throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
               "Validation of bean definition failed", ex);
      }
   }

   BeanDefinition oldBeanDefinition;

   oldBeanDefinition = this.beanDefinitionMap.get(beanName);

   if (oldBeanDefinition != null) {
      if (!isAllowBeanDefinitionOverriding()) {
         throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
               "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
               "': There is already [" + oldBeanDefinition + "] bound.");
      }
      else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
         // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
         if (this.logger.isWarnEnabled()) {
            this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
                  "' with a framework-generated bean definition: replacing [" +
                  oldBeanDefinition + "] with [" + beanDefinition + "]");
         }
      }
      else if (!beanDefinition.equals(oldBeanDefinition)) {
         if (this.logger.isInfoEnabled()) {
            this.logger.info("Overriding bean definition for bean '" + beanName +
                  "' with a different definition: replacing [" + oldBeanDefinition +
                  "] with [" + beanDefinition + "]");
         }
      }
      else {
         if (this.logger.isDebugEnabled()) {
            this.logger.debug("Overriding bean definition for bean '" + beanName +
                  "' with an equivalent definition: replacing [" + oldBeanDefinition +
                  "] with [" + beanDefinition + "]");
         }
      }
      this.beanDefinitionMap.put(beanName, beanDefinition);
   }
   else {
      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;
            if (this.manualSingletonNames.contains(beanName)) {
               Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
               updatedSingletons.remove(beanName);
               this.manualSingletonNames = updatedSingletons;
            }
         }
      }
      else {
         // Still in startup registration phase
         this.beanDefinitionMap.put(beanName, beanDefinition);
         this.beanDefinitionNames.add(beanName);
         this.manualSingletonNames.remove(beanName);
      }
      this.frozenBeanDefinitionNames = null;
   }

   //检查是否有同名的BeanDefinition已经在IOC容器中注册
   if (oldBeanDefinition != null || containsSingleton(beanName)) {
      //重置所有已经注册过的BeanDefinition的缓存
      resetBeanDefinition(beanName);
   }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MlpUyXgJ-1619436705011)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210418212555889.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KS7u1fzX-1619436705012)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210418212616191.png)]

时序图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a0LKaNld-1619436705013)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210418212632603.png)]

Bean创建流程

  • 通过最开始的关键时机点分析,我们知道Bean创建子流程入口在AbstractApplicationContext#refresh() 方法里的finishBeanFactoryInitialization(beanFactory)处

    //对配置了lazy-init属性的Bean进行预实例化处理
    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
       // Initialize conversion service for this context.
       //这是Spring3以后新加的代码,为容器指定一个转换服务(ConversionService)
       //在对某些Bean属性进行转换时使用
       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));
       }
    
       // Register a default embedded value resolver if no bean post-processor
       // (such as a PropertyPlaceholderConfigurer bean) registered any before:
       // at this point, primarily for resolution in annotation attribute values.
       if (!beanFactory.hasEmbeddedValueResolver()) {
          beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
       }
    
       // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
       String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
       for (String weaverAwareName : weaverAwareNames) {
          getBean(weaverAwareName);
       }
    
       // Stop using the temporary ClassLoader for type matching.
       //为了类型匹配,停止使用临时的类加载器
       beanFactory.setTempClassLoader(null);
    
       // Allow for caching all bean definition metadata, not expecting further changes.
       //缓存容器中所有注册的BeanDefinition元数据,以防被修改
       beanFactory.freezeConfiguration();
    
       // Instantiate all remaining (non-lazy-init) singletons.
       //对配置了lazy-init属性的单态模式Bean进行预实例化处理 实例化立刻加载的单例Bean
       beanFactory.preInstantiateSingletons();
    }
    
  • 继续进入DefaultListableBeanFactory类的preInstantiateSingletons方法,我们找到下面的代码,看到工厂Bean或者普通Bean,最终都是通过getBean的方法获取实例

//对配置lazy-init属性单态Bean的预实例化
@Override
public void preInstantiateSingletons() throws BeansException {
   if (this.logger.isDebugEnabled()) {
      this.logger.debug("Pre-instantiating singletons in " + this);
   }

   // Iterate over a copy to allow for init methods which in turn register new bean definitions.
   // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   // Trigger initialization of all non-lazy singleton beans...
   for (String beanName : beanNames) {
      //获取指定名称的Bean定义
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      //Bean不是抽象的,是单态模式的,且lazy-init属性配置为false
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         //如果指定名称的bean是创建容器的Bean
         if (isFactoryBean(beanName)) {
            //FACTORY_BEAN_PREFIX=”&”,当Bean名称前面加”&”符号
            //时,获取的是产生容器对象本身,而不是容器产生的Bean.
            //调用getBean方法,触发容器对Bean实例化和依赖注入过程
            final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
            //标识是否需要预实例化
            boolean isEagerInit;
            if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
               //一个匿名内部类
               isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) () ->
                     ((SmartFactoryBean<?>) factory).isEagerInit(),
                     getAccessControlContext());
            }
            else {
               isEagerInit = (factory instanceof SmartFactoryBean &&
                     ((SmartFactoryBean<?>) factory).isEagerInit());
            }
            if (isEagerInit) {
               //调用getBean方法,触发容器对Bean实例化和依赖注入过程
               getBean(beanName);
            }
         }
         else {
            getBean(beanName);
         }
      }
   }

   // Trigger post-initialization callback for all applicable beans...
   for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) {
         final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YwY7BOwo-1619436705014)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210418213438111.png)]

我们看出来触发容器对Bean实例化和依赖注入过程
//获取IOC容器中指定名称的Bean
@Override
public Object getBean(String name) throws BeansException {
   //doGetBean才是真正向IoC容器获取被管理Bean的过程
   return doGetBean(name, null, null, false);
}
进入doGetBean真正IOC容器获取被管理的Bean方法
//真正实现向IOC容器获取Bean的功能,也是触发依赖注入功能的地方
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

   //根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖
   //如果指定的是别名,将别名转换为规范的Bean名称
   final String beanName = transformedBeanName(name);
   Object bean;

   // Eagerly check singleton cache for manually registered singletons.
   //先从缓存中取是否已经有被创建过的单态类型的Bean
   //对于单例模式的Bean整个IOC容器中只创建一次,不需要重复创建
   Object sharedInstance = getSingleton(beanName);
   //IOC容器创建单例模式Bean实例对象
   if (sharedInstance != null && args == null) {
      if (logger.isDebugEnabled()) {
         //如果指定名称的Bean在容器中已有单例模式的Bean被创建
         //直接返回已经创建的Bean
         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的实例对象,主要是完成FactoryBean的相关处理
      //注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是
      //创建创建对象的工厂Bean,两者之间有区别
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
   }

   else {
      // Fail if we're already creating this bean instance:
      // We're assumably within a circular reference.
      //缓存没有正在创建的单例模式Bean
      //缓存中已经有已经创建的原型模式Bean
      //但是由于循环引用的问题导致实例化对象失败
      if (isPrototypeCurrentlyInCreation(beanName)) {
         throw new BeanCurrentlyInCreationException(beanName);
      }

      // Check if bean definition exists in this factory.
      //对IOC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否
      //能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器
      //的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找
      BeanFactory parentBeanFactory = getParentBeanFactory();
      //当前容器的父级容器存在,且当前容器中不存在指定名称的Bean
      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
         // Not found -> check parent.
         //解析指定Bean名称的原始名称
         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);
         }
      }

      //创建的Bean是否需要进行类型验证,一般不需要
      if (!typeCheckOnly) {
         //向容器标记指定的Bean已经被创建
         markBeanAsCreated(beanName);
      }

      try {
         //根据指定Bean名称获取其父级的Bean定义
         //主要解决Bean继承时子类合并父类公共属性问题
         final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         checkMergedBeanDefinition(mbd, beanName, args);

         // Guarantee initialization of beans that the current bean depends on.
         //获取当前Bean所有依赖Bean的名称
         String[] dependsOn = mbd.getDependsOn();
         //如果当前Bean有依赖Bean
         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 + "'");
               }
               //递归调用getBean方法,获取当前Bean的依赖Bean
               registerDependentBean(dep, beanName);
               //把被依赖Bean注册给当前依赖的Bean
               getBean(dep);
            }
         }

         // Create bean instance.
         //创建单例模式Bean的实例对象
         if (mbd.isSingleton()) {
            //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
            sharedInstance = getSingleton(beanName, () -> {
               try {
                  //创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义
                  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.
                  //显式地从容器单例模式Bean缓存中清除实例对象
                  destroySingleton(beanName);
                  throw ex;
               }
            });
            //获取给定Bean的实例对象
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
         }

         //IOC容器创建原型模式Bean实例对象
         else if (mbd.isPrototype()) {
            // It's a prototype -> create a new instance.
            //原型模式(Prototype)是每次都会创建一个新的对象
            Object prototypeInstance = null;
            try {
               //回调beforePrototypeCreation方法,默认的功能是注册当前创建的原型对象
               beforePrototypeCreation(beanName);
               //创建指定Bean对象实例
               prototypeInstance = createBean(beanName, mbd, args);
            }
            finally {
               //回调afterPrototypeCreation方法,默认的功能告诉IOC容器指定Bean的原型对象不再创建
               afterPrototypeCreation(beanName);
            }
            //获取给定Bean的实例对象
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
         }

         //要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中
         //配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中
         //比较常用,如:request、session、application等生命周期
         else {
            String scopeName = mbd.getScope();
            final Scope scope = this.scopes.get(scopeName);
            //Bean定义资源中没有配置生命周期范围,则Bean定义不合法
            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的实例对象
               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.
   //对创建的Bean实例对象进行类型检查
   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;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hMujrr83-1619436705015)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210418215332186.png)]

进入里面的方法

//获取给定Bean的实例对象,主要是完成FactoryBean的相关处理
protected Object getObjectForBeanInstance(
      Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

   // Don't let calling code try to dereference the factory if the bean isn't a factory.
   //容器已经得到了Bean实例对象,这个实例对象可能是一个普通的Bean,
   //也可能是一个工厂Bean,如果是一个工厂Bean,则使用它创建一个Bean实例对象,
   //如果调用本身就想获得一个容器的引用,则指定返回这个工厂Bean实例对象
   //如果指定的名称是容器的解引用(dereference,即是对象本身而非内存地址),
   //且Bean实例也不是创建Bean实例对象的工厂Bean
   if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
      throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
   }

   // Now we have the bean instance, which may be a normal bean or a FactoryBean.
   // If it's a FactoryBean, we use it to create a bean instance, unless the
   // caller actually wants a reference to the factory.
   //如果Bean实例不是工厂Bean,或者指定名称是容器的解引用,
   //调用者向获取对容器的引用,则直接返回当前的Bean实例
   if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
      return beanInstance;
   }

   //处理指定名称不是容器的解引用,或者根据名称获取的Bean实例对象是一个工厂Bean
   //使用工厂Bean创建一个Bean的实例对象
   Object object = null;
   if (mbd == null) {
      //从Bean工厂缓存中获取给定名称的Bean实例对象
      object = getCachedObjectForFactoryBean(beanName);
   }
   //让Bean工厂生产给定名称的Bean对象实例
   if (object == null) {
      // Return bean instance from factory.
      FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
      // Caches object obtained from FactoryBean if it is a singleton.
      //如果从Bean工厂生产的Bean是单态模式的,则缓存
      if (mbd == null && containsBeanDefinition(beanName)) {
         //从容器中获取指定名称的Bean定义,如果继承基类,则合并基类相关属性
         mbd = getMergedLocalBeanDefinition(beanName);
      }
      //如果从容器得到Bean定义信息,并且Bean定义信息不是虚构的,
      //则让工厂Bean生产Bean实例对象
      boolean synthetic = (mbd != null && mbd.isSynthetic());
      //调用FactoryBeanRegistrySupport类的getObjectFromFactoryBean方法,
      //实现工厂Bean生产Bean对象实例的过程
      object = getObjectFromFactoryBean(factory, beanName, !synthetic);
   }
   return object;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OFEzAXkV-1619436705016)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210418215529993.png)]

//Bean工厂生产Bean实例对象
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
   //Bean工厂是单态模式,并且Bean工厂缓存中存在指定名称的Bean实例对象
   if (factory.isSingleton() && containsSingleton(beanName)) {
      //多线程同步,以防止数据不一致
      synchronized (getSingletonMutex()) {
         //直接从Bean工厂缓存中获取指定名称的Bean实例对象
         Object object = this.factoryBeanObjectCache.get(beanName);
         //Bean工厂缓存中没有指定名称的实例对象,则生产该实例对象
         if (object == null) {
            //调用Bean工厂的getObject方法生产指定Bean的实例对象
            object = doGetObjectFromFactoryBean(factory, beanName);
            // Only post-process and store if not put there already during getObject() call above
            // (e.g. because of circular reference processing triggered by custom getBean calls)
            Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
            if (alreadyThere != null) {
               object = alreadyThere;
            }
            else {
               if (shouldPostProcess) {
                  try {
                     object = postProcessObjectFromFactoryBean(object, beanName);
                  }
                  catch (Throwable ex) {
                     throw new BeanCreationException(beanName,
                           "Post-processing of FactoryBean's singleton object failed", ex);
                  }
               }
               //将生产的实例对象添加到Bean工厂缓存中
               this.factoryBeanObjectCache.put(beanName, object);
            }
         }
         return object;
      }
   }
   //调用Bean工厂的getObject方法生产指定Bean的实例对象
   else {
      Object object = doGetObjectFromFactoryBean(factory, beanName);
      if (shouldPostProcess) {
         try {
            object = postProcessObjectFromFactoryBean(object, beanName);
         }
         catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
         }
      }
      return object;
   }
}

lazy-init延迟加载机制原理

  • lazy-init延迟加载机制分析

普通Bean的初始化是在容器启动初始化阶段执行的,而被lazy-intit=true修饰的bean则是在从容器里第一次进行context.getBean()时进行触发

Spring启动的时候会把所有的Bean信息(包括XML和注解)解析转成Spring能够识别的BeanDefinition并存在HashMap里供下面的初始化使用,然后对每个BeanDefinition进行处理,如果是懒加载则在容器初始化阶段不会处理,其他的则在初始化阶段进行初始化并依赖注入。

//DefaultListableBeanFactory类里面的实现方法

//对配置lazy-init属性单态Bean的预实例化
@Override
public void preInstantiateSingletons() throws BeansException {
   if (this.logger.isDebugEnabled()) {
      this.logger.debug("Pre-instantiating singletons in " + this);
   }

   // Iterate over a copy to allow for init methods which in turn register new bean definitions.
   // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   // Trigger initialization of all non-lazy singleton beans...
   for (String beanName : beanNames) {
      //获取指定名称的Bean定义
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      //Bean不是抽象的,是单态模式的,且lazy-init属性配置为false
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         //如果指定名称的bean是创建容器的Bean
         if (isFactoryBean(beanName)) {
            //FACTORY_BEAN_PREFIX=”&”,当Bean名称前面加”&”符号
            //时,获取的是产生容器对象本身,而不是容器产生的Bean.
            //调用getBean方法,触发容器对Bean实例化和依赖注入过程
            final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
            //标识是否需要预实例化
            boolean isEagerInit;
            if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
               //一个匿名内部类
               isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) () ->
                     ((SmartFactoryBean<?>) factory).isEagerInit(),
                     getAccessControlContext());
            }
            else {
               isEagerInit = (factory instanceof SmartFactoryBean &&
                     ((SmartFactoryBean<?>) factory).isEagerInit());
            }
            if (isEagerInit) {
               //调用getBean方法,触发容器对Bean实例化和依赖注入过程
               getBean(beanName);
            }
         }
         else {
            getBean(beanName);
         }
      }
   }

   // Trigger post-initialization callback for all applicable beans...
   for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) {
         final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值