Spring Bean生命周期源码详解

本文详细探讨了Spring框架中Bean的生命周期,从BeanDefinition的生成到Bean的实例化、依赖注入、初始化、销毁等各个阶段,包括源码分析、 Aware回调、生命周期方法的执行等,帮助读者深入理解Spring容器对Bean的管理过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Bean生命周期源码

我们创建一个ApplicationContext对象时,这其中主要会做两件时间:包扫描得到BeanDefinition的set集合,创建非懒加载的单例Bean

public static void main(String[] args) {
   

   // 创建一个Spring容器
   AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

   UserService userService = (UserService) context.getBean("userService");
   userService.test();
}


生成BeanDefinition

在线流程图

在这里插入图片描述

首先我们来看AnnotationConfigApplicationContext的构造方法

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
   
   // 构造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner
    // 这里创建ClassPathBeanDefinitionScanner时,还会添加一个includeFilters,包含@Component注解
   this();
   register(componentClasses);
   refresh();
}

接下来是refresh()方法

public void refresh() throws BeansException, IllegalStateException {
   
    ...
    // 会拿到上一步创建的ClassPathBeanDefinitionScanner,调用scan方法进行包扫描
    invokeBeanFactoryPostProcessors(beanFactory);
    
    /// 会创建非懒加载单例bean
    finishBeanFactoryInitialization(beanFactory);
    ...
}


先看包扫描的逻辑,ClassPathBeanDefinitionScanner类主要做的事情就是包扫描完后再将得到的BeanDefinition注册进Spring容器中。

scan(String... basePackages)方法中会调用doScan(String... basePackages)方法

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
   
		Assert.notEmpty(basePackages, "At least one base package must be specified");
		// 创建一个set集合存放扫描到的BeanDefinition
		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
		// 可以传多个包路径,但我们一般都只传一个包路径
		for (String basePackage : basePackages) {
   

			// 调这个方法就会得到BeanDefinition集合,该方法扫描得到的BeanDefinition对象中主要只是有metadata、beanclass和source属性
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
			// 遍历BeanDefinition集合,解析类的元数据信息为BeanDefinition的其他属性赋值
			for (BeanDefinition candidate : candidates) {
   
				// 解析类上@Scope注解信息
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());

				// 得到beanName,首先解析@Component注解中有没有指定beanName,如果没有指定再去按照默认是生成规则生成
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);

				// 包扫描的ScannedGenericBeanDefinition和AnnotatedGenericBeanDefinition,这两个BeanDefinition都满足下面两个if
				if (candidate instanceof AbstractBeanDefinition) {
   
					// 给BeanDefinition赋一些默认值
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
   
					// 解析@Lazy、@Primary、@DependsOn、@Role、@Description
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}

				// 检查Spring容器beanDefinitionMap中是否已经存在该beanName,不存在才会走下面的if逻辑
				if (checkCandidate(beanName, candidate)) {
   
					// BeanDefinition中没有存beanName,而是把他们封装为了一个BeanDefinitionHolder对象
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					// 保存到set集合中
					beanDefinitions.add(definitionHolder);

					// 这里又从BeanDefinitionHolder取出beanName和BeanDefinition,把BeanDefinition注册进容器中的beanDefinitionMap中
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;
	}

findCandidateComponents(String basePackage)方法逻辑

public Set<BeanDefinition> findCandidateComponents(String basePackage) {
   
   if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
   
       // 我们可以定义一个resources/META-INF/Spring.components文件,然后就仅仅匹配个文件中指定的类与注解
       // 而不扫描指定包路径下的所有*.class文件
       return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
   }
   else {
   
      // 我们创建的Spring项目一般会走这个逻辑
      return scanCandidateComponents(basePackage);
   }
}

scanCandidateComponents(String basePackage)方法逻辑,该方法扫描得到的BeanDefinition对象中主要只是有beanclass和source属性

private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
   
   // 返回值 存放BeanDefinition对象的Set集合
   Set<BeanDefinition> candidates = new LinkedHashSet<>();
   try {
   
      // 获取指定包路径下所有的*.class文件资源,将 com.hs 变为 classpath*:com/hs/**/*.class
      String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
            resolveBasePackage(basePackage) + '/' + this.resourcePattern;

      // 封装为Resource对象
      Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);

      boolean traceEnabled = logger.isTraceEnabled();
      boolean debugEnabled = logger.isDebugEnabled();
      // 遍历每一个class文件资源对象
      for (Resource resource : resources) {
   
         if (traceEnabled) {
   
            logger.trace("Scanning " + resource);
         }
         // 判断当前资源是否可读
         if (resource.isReadable()) {
   
            try {
   
               // 得到元数据读取器
               MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
               // excludeFilters、includeFilters判断,判断类上是否有@Component,再去判断是否符合@Conditional
               if (isCandidateComponent(metadataReader)) {
   
                  // 当上面的条件满足后,才会将当前类封装为BeanDefinition对象
                  ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                  sbd.setSource(resource);

                  // 这里还会对当前类进行进一步判断,这个条件满足之后才会将BeanDefinition对象添加进set集合中
                  if (isCandidateComponent(sbd)) {
   
                     if (debugEnabled) {
   
                        logger.debug("Identified candidate component class: " + resource);
                     }
                     candidates.add(sbd);
                  }
                  ... ...
            }
            catch (Throwable ex) {
   
               throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, ex);
            }
         }
         else {
   
            ...
         }
      }
   }
   catch (IOException ex) {
   
      throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
   }
   return candidates;
}


Spring容器启动时创建单例Bean

在线流程图网址
在这里插入图片描述

首先我们来看AnnotationConfigApplicationContext的构造方法

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
   
   // 构造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner
   // 这里创建ClassPathBeanDefinitionScanner时,还会添加一个includeFilters,包含@Component注解
   this();
   register(componentClasses);
   refresh();
}

接下来是refresh()方法

public void refresh() throws BeansException, IllegalStateException {
   
    ...
    // 会拿到上一步创建的ClassPathBeanDefinitionScanner,调用scan方法进行包扫描
    invokeBeanFactoryPostProcessors(beanFactory);
    
    /// 会创建非懒加载单例bean
    finishBeanFactoryInitialization(beanFactory);
    ...
}

现在就跟finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)方法

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   
   
    ... ...
       
   // 实例化非懒加载的单例Bean
   beanFactory.preInstantiateSingletons();
}

最终创建的方法是preInstantiateSingletons()

// 首先遍历beanNames集合,将包扫描时创建的BeanDefinition全部完成合并操作
// 判断非懒加载的单例bean
// 判断是不是FactoryBean,如果是则创建FactoryBean对象,如果不是则创建Bean对象
// 所有非懒加载单例Bean都存入单例池之后,再遍历一次beanNames集合,判断有没有实现SmartInitializingSingleton接口
public void preInstantiateSingletons() throws BeansException {
   
   if (logger.isTraceEnabled()) {
   
      logger.trace("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);

   // 所以非懒加载单例Bean初始化
   for (String beanName : beanNames) {
   
      // 根据beanName 获取合并后的BeanDefinition,具体合并方法在下面会详细分析
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      // 判断不是抽象的BeanDefinition、单例、不是懒加载
      // 一般使用注解方式创建的Bean都不是抽象的,使用XML方式定义Bean时有一个abstract属性来指定
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
   
         // 判断当前类是不是FactoryBean
         if (isFactoryBean(beanName)) {
   
            // 获取FactoryBean对象,加&前缀后获取的是factoryBean对象,而不是getObject()方法返回的对象
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
   
               FactoryBean<?> factory = (FactoryBean<?>) bean;
               // 判断当前类有没有实现SmartFactoryBean接口,如果实现了则调用isEagerInit()方法,将方法返回值赋值给isEagerInit
               boolean isEagerInit;
               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
   
                  isEagerInit = AccessController.doPrivileged(
                        (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                        getAccessControlContext());
               }
               else {
   
                  isEagerInit = (factory 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值