Bean生命周期源码(一)

2023-12-22 09:38:24

一. 简介

Spring最重要的功能就是帮助程序员创建对象(也就是IOC),而Spring就是为创建Bean对象做准备,所以我们需要先搞明白Spring到底是如何创建Bean的,也就是先弄明白Bean的生命周期。

在这里插入图片描述

二. Bean的生成过程

1. 容器启动

在生成Bean之前,我们首先需要将容器启动起来。启动容器主要做两件事:

  1. 扫描指定路径下的类
  2. 创建非懒加载的Bean

下面我们大致看一下这两步的源码:

首先以下代码创建容器,AppConfig是我们的配置类,配置类包扫描路径

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

调用AnnotationConfigApplicationContext的构造函数

		public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		// 构造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner
		this();
		//注册配置类
		register(componentClasses);
		refresh();
	}
	
	public AnnotationConfigApplicationContext() {
		StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
		// 额外会创建StandardEnvironment,这个就是生成BeanDefinition的阅读器,以及创建ClassPathBeanDefinitionScanner这个扫描器
		this.reader = new AnnotatedBeanDefinitionReader(this);
		createAnnotatedBeanDefReader.end();
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");是JFR机制,是JDK底层用于记录Java程序运行性能的,如上面代码就是使用createAnnotatedBeanDefReader.end();包裹住了 this.reader = new AnnotatedBeanDefinitionReader(this);,即

refresh()方法是创建容器时,强制必须调用的方法。refresh() 方法是 Spring 框架中最为核心的方法之一,可以说整个 Spring 容器的运作机制就是围绕着这个方法来展开的,在Spring框架中,ApplicationContext是容器的核心接口,负责管理和维护Spring应用程序中的所有bean。当应用程序启动时,Spring容器会自动创建并加载所有的bean定义,并将其实例化为bean对象。随着应用程序的运行,这些bean对象可能需要被修改、替换、删除等操作,这时就需要刷新ApplicationContext来更新bean的状态。

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			// 这里会判断能否刷新,并且返回一个BeanFactory, 刷新不代表完全情况,主要是先执行Bean的销毁,然后重新生成一个BeanFactory,再在接下来的步骤中重新去扫描等等
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			// 准备BeanFactory
			// 1. 设置BeanFactory的类加载器、SpringEL表达式解析器、类型转化注册器
			// 2. 添加三个BeanPostProcessor,注意是具体的BeanPostProcessor实例对象
			// 3. 记录ignoreDependencyInterface
			// 4. 记录ResolvableDependency
			// 5. 添加三个单例Bean
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				// 子类来设置一下BeanFactory
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");

				// Invoke factory processors registered as beans in the context.
				// BeanFactory准备好了之后,执行BeanFactoryPostProcessor,开始对BeanFactory进行处理
				// 默认情况下:
				// 此时beanFactory的beanDefinitionMap中有6个BeanDefinition,5个基础BeanDefinition+AppConfig的BeanDefinition
				// 而这6个中只有一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor
				// 这里会执行ConfigurationClassPostProcessor进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中
				// 注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行
				invokeBeanFactoryPostProcessors(beanFactory);  // scanner.scan()

				// Register bean processors that intercept bean creation.
				// 将扫描到的BeanPostProcessors实例化并排序,并添加到BeanFactory的beanPostProcessors属性中去
				registerBeanPostProcessors(beanFactory);

				beanPostProcess.end();

				// Initialize message source for this context.
				// 设置ApplicationContext的MessageSource,要么是用户设置的,要么是DelegatingMessageSource
				initMessageSource();

				// Initialize event multicaster for this context.
				// 设置ApplicationContext的applicationEventMulticaster,要么是用户设置的,要么是SimpleApplicationEventMulticaster
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// 给子类的模板方法
				onRefresh();

				// Check for listener beans and register them.
				// 把定义的ApplicationListener的Bean对象,设置到ApplicationContext中去,并执行在此之前所发布的事件
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
     //完成beanFactory的初始化
	finishBeanFactoryInitialization(beanFactory);
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}

finishBeanFactoryInitialization(beanFactory);用于直接完成BeanFacotory的初始化,
invokeBeanFactoryPostProcessors(beanFactory);就完成了包的扫描

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		// 如果BeanFactory中存在名字叫conversionService的Bean,则设置为BeanFactory的conversionService属性
		// ConversionService是用来进行类型转化的
		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 BeanFactoryPostProcessor
		// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		// 设置默认的占位符解析器  ${xxx}  ---key
		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.
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		// 实例化非懒加载的单例Bean
		beanFactory.preInstantiateSingletons();
	}

上面beanFactory.preInstantiateSingletons();就实现了对非懒加载的单例Bean的加载

2. BeanDefitnion扫描以及注册

上面讲了Spring的基本启动流程,主要是做两件事包扫描,以及注册非懒加载的单例bean。前面我们说到包扫描Spring定义了一个包扫描器:

this.scanner = new ClassPathBeanDefinitionScanner(this);

这个类的核心方法就是scan方法

public class ClassPathBeanDefinitionScanner extends 
//参数为传进来的一系列包路径
ClassPathScanningCandidateComponentProvider {
		public int scan(String... basePackages) {
//registry是一个常量,类型是BeanDefinitionRegistry,这是一个接口,定义类BeanDefinition注册的规范,它实际调用的是DefaultListBeanFactory
		int beanCountAtScanStart = this.registry.getBeanDefinitionCount();

		doScan(basePackages);

		// Register annotation config processors, if necessary.
		if (this.includeAnnotationConfig) {
			AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
		}

		return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
	}

}

scan方法中doscan方法实现了实际扫描的逻辑,让我们看一下它的代码

//返回值是一个set集合
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
		Assert.notEmpty(basePackages, "At least one base package must be specified");
		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
		for (String basePackage : basePackages) {

			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);

			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) {
					// 解析@Lazy、@Primary、@DependsOn、@Role、@Description
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}
				// 检查Spring容器中是否已经存在该beanName
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);

					// 注册
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;
	}

doScan方法主要的逻辑就是拿到路径,然后扫描路径下的class,然后解析class拿到BeanDefinition。上面Set<BeanDefinition> candidates = findCandidateComponents(basePackage);就获取了所有的BeanDefinition,让我们看看findCandidateComponents底层

	public Set<BeanDefinition> findCandidateComponents(String basePackage) {
		if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
			return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
		}
		else {
			return scanCandidateComponents(basePackage);
		}
	}

if (this.componentsIndex != null && indexSupportsIncludeFilters()) {这段代码的作用其实就是可以加快扫描过程,我们知道如果我们项目中类很多,扫描是一个很费时的过程,于是Spring引入了索引机制,可以在Resources文件夹下定义一个spring.components文件,写入类似于下面的内容

com.jack.serviece.userService=org.springframework.stereotype.Component

这样,就可以按照这个索引去直接找相应的类就行了,但如果我们加了这个文件,那么我们就需要将所有需要加载为bean的类的信息都写入这个文件中。

findCandidateComponents调用了scanCandidateComponents方法


	private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
	//定义set集合
		Set<BeanDefinition> candidates = new LinkedHashSet<>();
		try {
			// 构造路径URI
			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +				resolveBasePackage(basePackage) + '/' + this.resourcePattern;
//获取包路径下的所有class文件
			Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);

			boolean traceEnabled = logger.isTraceEnabled();
			boolean debugEnabled = logger.isDebugEnabled();
			//遍历所有文件的resource
			for (Resource resource : resources) {
				if (traceEnabled) {
					logger.trace("Scanning " + resource);
				}
				if (resource.isReadable()) {
					try {
					//定义元数据读取器,读取每个类的元数据
						MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
						// excludeFilters、includeFilters判断
						if (isCandidateComponent(metadataReader)) { // 判断该类是否有Component注解
							ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
							sbd.setSource(resource);

							if (isCandidateComponent(sbd)) {
								if (debugEnabled) {
									logger.debug("Identified candidate component class: " + resource);
								}
								candidates.add(sbd);
							}
							else {
								if (debugEnabled) {
									logger.debug("Ignored because not a concrete top-level class: " + resource);
								}
							}
						}
						else {
							if (traceEnabled) {
								logger.trace("Ignored because not matching any filter: " + resource);
							}
						}
					}
					catch (Throwable ex) {
						throw new BeanDefinitionStoreException(
								"Failed to read candidate component class: " + resource, ex);
					}
				}
				else {
					if (traceEnabled) {
						logger.trace("Ignored because not readable: " + resource);
					}
				}
			}
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
		}
		return candidates;
	}

看看 String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + '/' + this.resourcePattern;是怎么拼的,例如我们传入的路径为com.zhouyuResourcePatternResolver.CLASSPATH_ALL_URL_PREFIXclasspath*:,然后this.resourcePattern**/*.class,所以最后就匹配为classpath*:com/zhouyu/**/*.class

上面代码中isCandidateComponent(metadataReader)就判断了扫描到的类能不能装为bean

//参数为元数据读取器
	protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
	//ComponentSacn注解有一个excludeFilters属性,排除某个类作为bean,如果当前这个类与某个excludeFilters匹配,就不能加载为bean
		for (TypeFilter tf : this.excludeFilters) {
			if (tf.match(metadataReader, getMetadataReaderFactory())) {
				return false;
			}
		}

		// 符合includeFilters的会进行条件匹配,通过了才是Bean,也就是先看有没有@Component,再看是否符合@Conditional(如果ComponentSacn我们没有手动指定includeFilters,Spring会帮我们讲所有加了Component注解的类加入到includeFilters的对象中)
		for (TypeFilter tf : this.includeFilters) {
		//先判断当前类是否有Component注解,或者是在includeFilters汇总指定类
			if (tf.match(metadataReader, getMetadataReaderFactory())) {
				return isConditionMatch(metadataReader);
				//isConditionMatch
			}
		}
		return false;
	}

上面代码中就是在判断一个类有没有资格成为一个bean,首先第一个条件是有Component注解,然后调用isConditionMatch判断第二个条件,我们看看它底层

	private boolean isConditionMatch(MetadataReader metadataReader) {
		if (this.conditionEvaluator == null) {
			this.conditionEvaluator =
					new ConditionEvaluator(getRegistry(), this.environment, this.resourcePatternResolver);
		}
		//调用了shouldSkip,参数为当前类的所有注解信息
		return !this.conditionEvaluator.shouldSkip(metadataReader.getAnnotationMetadata());
	}

public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {
//如果metadata为空,或没有加Conditional注解,直接返返回false
		if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
		//false就表示该类可以成为一个bean,如果
			return false;
		}
       //如果当前类上有Conditional就会之间matches方法来判断是否符合条件,这里就不细讲了
		if (phase == null) {
			if (metadata instanceof AnnotationMetadata &&
					ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
				return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION);
			}
			return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN);
		}

判断完扫描路径下的类能否成为bean后我们回到scanCandidateComponents方法

if (isCandidateComponent(metadataReader)) { // @Component-->includeFilters判断
							ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
							sbd.setSource(resource);

							if (isCandidateComponent(sbd)) {
								if (debugEnabled) {
									logger.debug("Identified candidate component class: " + resource);
								}
								candidates.add(sbd);
							}
							else {
								if (debugEnabled) {
									logger.debug("Ignored because not a concrete top-level class: " + resource);
								}
							}
						}

进入上面if,执行ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);来生成BeanDifinition

	public ScannedGenericBeanDefinition(MetadataReader metadataReader) {
		Assert.notNull(metadataReader, "MetadataReader must not be null");
		//将当前类的所有注解加入到对应的元数据信息类metadata中
		this.metadata = metadataReader.getAnnotationMetadata();
		// 这里只是把className设置到BeanDefinition中,并没有真正的实例化BeanDefinition
		setBeanClassName(this.metadata.getClassName());
		setResource(metadataReader.getResource());
	}

	@Override
	public void setBeanClassName(@Nullable String beanClassName) {
		this.beanClass = beanClassName;
	}

上面ScannedGenericBeanDefinition并没有真正的去实例化BeanDefininition,而只是将要实例化为Bean的类的名字赋值给了对应的BeanDefinition相关属性中,等真正要用到这个bean的时候再去实例化,继续回到scanCandidateComponents。

if (isCandidateComponent(sbd)) {
								if (debugEnabled) {
									logger.debug("Identified candidate component class: " + resource);
								}
								candidates.add(sbd);
							}
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
//获取当前类的元数据信息
		AnnotationMetadata metadata = beanDefinition.getMetadata();
//metadata.isIndependent判断当前类是否是独立类(顶级类,内部类的最外层类,以及静态内部类都是独立类),如果是独立类就能成为bean,否则不能metadata.isConcrete判断当前类是否是接口和抽象类,接口和抽象类都不能被实例化为Bean
//metadata.hasAnnotatedMethods(Lookup.class.getName()))),如果当前类确实是一个抽象类,但它类中有被Lookup注解注释的方法
		return (metadata.isIndependent() && (metadata.isConcrete() ||
				(metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
	}

isCandidateComponent方法从类本身信息来判断该类是否能成为一个bean,如果所有条件都符合就会调用
candidates.add(sbd);,将当前的BeanDefinition加到前面定义的set容器中。至此scanCandidateComponents基本执行完毕了,回到doscan方法,继续向下运行:

//下面开始遍历BeanDefinition的set集合,进一步完善BeanDefiniton信息
for (BeanDefinition candidate : candidates) {
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
//setScope设置当前BeanDefinition对应的Bean的Scope信息
		candidate.setScope(scopeMetadata.getScopeName());
//生成bean的名字
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);

				if (candidate instanceof AbstractBeanDefinition) {
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
					// 解析@Lazy、@Primary、@DependsOn、@Role、@Description
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}

				// 检查Spring容器中是否已经存在该beanName
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);

					// 注册
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;

String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);这句代码生成bean的名字,我们知道当我们使用Component注解定义一个类为bean时,我们可以自己指定bean的名字,也可以系统帮我们默认生成,让我们看看它底层动作是怎么样的

	@Override
	public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
		if (definition instanceof AnnotatedBeanDefinition) {
			// 获取注解所指定的beanName,这里就是判断Component注解有没有指定名字
			String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
			if (StringUtils.hasText(beanName)) {
				// Explicit bean name found.
				return beanName;
			}
		}
		// Fallback: generate a unique default bean name.
		//如果Component注解中没有指定bean的名字,就会帮我们生成一个默认的名字
		return buildDefaultBeanName(definition, registry);
	}

	protected String buildDefaultBeanName(BeanDefinition definition) {
		String beanClassName = definition.getBeanClassName();
		Assert.state(beanClassName != null, "No bean class name set");
		String shortClassName = ClassUtils.getShortName(beanClassName);
		return Introspector.decapitalize(shortClassName);
	}

    public static String decapitalize(String name) {
        if (name == null || name.length() == 0) {
            return name;
        }
        //如果类名的长度大于1,且第一个字符和地二个字符都是大写,直接返回类名
        if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
                        Character.isUpperCase(name.charAt(0))){
            return name;
        }
        char chars[] = name.toCharArray();
        //将类名第一个字符转换为小写
        chars[0] = Character.toLowerCase(chars[0]);
        return new String(chars);
    }

上面代码的逻辑就是帮我们的Bean给一个名字,如果我们在Component注解中指定了名字,它就会使用我们指定的名字,如果没有指定,它会根据类名帮我们来指定,如果类名的前面两个字母都是大写,就直接拿当前类名作为bean的名称,否则将类名首字母小写后作为bean的名字。生成完名字后继续回到doscan的方法。

//下面开始遍历BeanDefinition的set集合,进一步完善BeanDefiniton信息
for (BeanDefinition candidate : candidates) {
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
//setScope设置当前BeanDefinition对应的Bean的Scope信息
		candidate.setScope(scopeMetadata.getScopeName());
//生成bean的名字
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);

				if (candidate instanceof AbstractBeanDefinition) {
//BeanDefinition生成前置处理器,帮我们初始化一些beandefinition的基本信息
		postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
					// 解析@Lazy、@Primary、@DependsOn、@Role、@Description
								AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}

				// 检查Spring容器中是否已经存在该beanName
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);

					// 注册
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;

在BeanDefinition中没有存储对应的Beanname,BeanDefinitionHolder就是将beanName与对于的BeanDefintion绑定起来

前面我们基本上已经完成了BeanDefinition的初始化的大部分动作,执行checkCandidate(beanName, candidate),这里就是判断,Spring容器中是否已经存在了当前的beanname

protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException {
//如果当前容器中不包含当前的beanName,就返回ture
		if (!this.registry.containsBeanDefinition(beanName)) {
			return true;
		}
		//如果包含,首先获取这个同名的BeanDefinition
		BeanDefinition existingDef = this.registry.getBeanDefinition(beanName);
		BeanDefinition originatingDef = existingDef.getOriginatingBeanDefinition();
		if (originatingDef != null) {
			existingDef = originatingDef;
		}
		// 是否兼容,如果兼容返回false表示不会重新注册到Spring容器中,如果不冲突则会抛异常。
		if (isCompatible(beanDefinition, existingDef)) {
			return false;
		}
		throw new ConflictingBeanDefinitionException("Annotation-specified bean name '" + beanName +
				"' for bean class [" + beanDefinition.getBeanClassName() + "] conflicts with existing, " +
				"non-compatible bean definition of same name and class [" + existingDef.getBeanClassName() + "]");
	}

在平常的开发过程中,我们知道如果我们的Beanname重复的话一般会抛出冲突异常,但其实源码中加了isCompatible(beanDefinition, existingDef)这段代码来判断同名beanDefinition的兼容性

//如果是容器多次扫描的情况,例如我们第一次扫描已经将当前类的bean加载到容器中了,第二次扫描发现和已经存在的beandefitntion的newDefinition.getSource相同,说明当前beandefintion已经存在了,我们就不需要继续生成beandefintion了
	protected boolean isCompatible(BeanDefinition newDefinition, BeanDefinition existingDefinition) {
		return (!(existingDefinition instanceof ScannedGenericBeanDefinition) ||  // explicitly registered overriding bean
				(newDefinition.getSource() != null && newDefinition.getSource().equals(existingDefinition.getSource())) ||  // scanned same file twice
				newDefinition.equals(existingDefinition));  // scanned equivalent class twice
	}

上面就是验证了BeanDefitnion对应的beanName是否存在,如果存在但存在了其通过了兼容性判断,就会直接返回当前的BeanDefinition的set集合,如果不存在下面就开始真正的注册BeanDefinition了,在doscan方法中调用registerBeanDefinition方法

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

		// Register bean definition under primary name.
		//获得beanname
		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的核心注册逻辑是在registry.registerBeanDefinition方法中

@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 {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}
         //获取同名的BeanDefinition
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			// 默认是允许BeanDefinition覆盖的
			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 + "]");
				}
			}
	//放入一个map集合中,覆盖原来的beandefinition
	this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		//如果不存在同名beanname
		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();
		}
	}

上面就是将BeanDefinition的信息放入到一个一个集合中。上面就完成了BeanDefinition扫描以及注册的所有功能,下面就开始实例化当例bean。

3. 实现非懒加载的单例bean

执行完doscan()bean的扫描和注册就已经完成了,现在容器中的hashmap就已经存放了我们的BeanDefinition信息了,下面就可以根据这些信息来实现我们非懒加载的bean的初始化动作。

上面invokeBeanFactoryPostProcessors就完成了扫描以及BeanDefinition的注册动作,下面开始执行refresh方法中的finishBeanFactoryInitialization,实现非懒加载的单例bean的初始化。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		// 如果BeanFactory中存在名字叫conversionService的Bean,则设置为BeanFactory的conversionService属性
		// ConversionService是用来进行类型转化的
		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 BeanFactoryPostProcessor
		// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		// 设置默认的占位符解析器  ${xxx}  ---key
		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.
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		// 实例化非懒加载的单例Bean
		beanFactory.preInstantiateSingletons();
	}

上面方法中实现非懒加载的单例Bean是beanFactory.preInstantiateSingletons这句代码实现的。

@Override
	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.
		//获取bean的名字,在注册bean时已经将beandefitnitionname也放到了一个集合中
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		//遍历beandefitnitionname
		for (String beanName : beanNames) {
			// 获取合并后的BeanDefinition(bean之间存在继承关系),生成一个新的BeanDefinition
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            //判断当前beanDefitnion是否是抽象的(在xml通过abstract定义,抽象的beanDefitnion不能创建bean,其它bean可以继承这个抽象的beanDefitnion,然后获取其属性)是否是单例以及懒加载
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			//判断当前bean是不是FacotoryBean(
				if (isFactoryBean(beanName)) {
					// 获取FactoryBean对象
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						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) {
							// 创建真正的Bean对象(getObject()返回的对象)
							getBean(beanName);
						}
					}
				}
				else {
				//不是factorybean就获取bean(创建Bean的逻辑也是在该方法中调用的)
					// 创建Bean对象
					getBean(beanName);
				}
			}
		}
	
		// 所有的非懒加载单例Bean都创建完了后
		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
				smartInitialize.end();
			}
		}
	}

首先上面会将一些继承关系的bean合并成一个新的bean,类型为RootBeanDefinition,调用的方法为
getMergedLocalBeanDefinition

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
		// Quick check on the concurrent map first, with minimal locking.
		RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
		if (mbd != null && !mbd.stale) {
		//如果this.mergedBeanDefinitions这个map中以及存储了该RootBeanDefinitions,我直接返回即可
			return mbd;
		}
		//否则调用getMergedBeanDefinition实现合并操作
		return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
	}

该方法中首先调用getBeanDefinition(beanName)根据beanName获取相应的BeanDefinition对象

	@Override
	public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
//private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

//this.beanDefinitionMap是存放beanDefinition的集合
		BeanDefinition bd = this.beanDefinitionMap.get(beanName);
		//如果没有获取就记录日志抛出异常
		if (bd == null) {
			if (logger.isTraceEnabled()) {
				logger.trace("No bean named '" + beanName + "' found in " + this);
			}
			throw new NoSuchBeanDefinitionException(beanName);
		}
		//否则就返回获取到的BeanDefinitinon
		return bd;
	}

回到getMergedLocalBeanDefinition方法,然后调用
getMergedBeanDefinition(beanName, getBeanDefinition(beanName))方法

	protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
			throws BeanDefinitionStoreException {

		return getMergedBeanDefinition(beanName, bd, null);
	}

protected RootBeanDefinition getMergedBeanDefinition(
			String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
			throws BeanDefinitionStoreException {
//线程安全的
		synchronized (this.mergedBeanDefinitions) {
			RootBeanDefinition mbd = null;
			RootBeanDefinition previous = null;

			// 如果containingBd为null(表示当前 Bean不是另一个Bean的内部成员),则直接从缓存中获取。
			if (containingBd == null) {
			//通过 this.mergedBeanDefinitions.get(beanName) 尝试从缓存中获取已合并的 Bean 定义(mbd)
				mbd = this.mergedBeanDefinitions.get(beanName);
			}
//如果缓存中的 Bean 定义 (mbd) 不可用或者过期(stale 为 true),则进行后续的合并逻辑。
			if (mbd == null || mbd.stale) {
				previous = mbd;
				//如果当前 Bean 没有父 Bean(bd.getParentName() == null),则直接使用给定的 Bean 定义 bd 的副本,可以通过 cloneBeanDefinition 或者创建新的 RootBeanDefinition 实例实现。
				if (bd.getParentName() == null) {
					// Use copy of given root bean definition.
					if (bd instanceof RootBeanDefinition) {
						mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
					}
					else {
						mbd = new RootBeanDefinition(bd);
					}
				}
				else {
				//如果如果当前 Bean 有父 Bean,则需要合并父子 Bean 定义。
					// Child bean definition: needs to be merged with parent.
					// pbd表示parentBeanDefinition
					BeanDefinition pbd;
					try {
					//首先,尝试获取父 Bean 的合并定义(pbd)。
						String parentBeanName = transformedBeanName(bd.getParentName());
						//如果父 Bean 的名称与当前 Bean 的名称相同,说明是同一个 Bean,直接从父 BeanFactory 中获取合并定义。

						if (!beanName.equals(parentBeanName)) {
							pbd = getMergedBeanDefinition(parentBeanName);
						}
						else {
						//否则,通过 getMergedBeanDefinition 方法递归获取父 Bean 的合并定义。
							BeanFactory parent = getParentBeanFactory();
							if (parent instanceof ConfigurableBeanFactory) {
								pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
							}
							else {
								throw new NoSuchBeanDefinitionException(parentBeanName,
										"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
												"': cannot be resolved without a ConfigurableBeanFactory parent");
							}
						}
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
								"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
					}

					// Deep copy with overridden values.
					// 子BeanDefinition的属性覆盖父BeanDefinition的属性,这就是合并
					//使用 RootBeanDefinition 的构造函数创建当前 Bean 的合并定义,并通过 overrideFrom 方法将子 Bean 的属性覆盖到父 Bean 上。
					mbd = new RootBeanDefinition(pbd);
					mbd.overrideFrom(bd);
				}

				// Set default singleton scope, if not configured before.
				if (!StringUtils.hasLength(mbd.getScope())) {
					mbd.setScope(SCOPE_SINGLETON);
				}
				if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
					mbd.setScope(containingBd.getScope());
				}

				// Cache the merged bean definition for the time being
				// (it might still get re-merged later on in order to pick up metadata changes)
				if (containingBd == null && isCacheBeanMetadata()) {
					this.mergedBeanDefinitions.put(beanName, mbd);
				}
			}
			if (previous != null) {
				copyRelevantMergedBeanDefinitionCaches(previous, mbd);
			}
			return mbd;
		}
	}

上面就是合并bean的所有逻辑,合并完bean后我们回到preInstantiateSingletons方法,判断当前bean是否为懒加载,如果不是懒加载调用,就通过isFactoryBean(beanName)方法判断当前bean是不是FacotoryBean

@Override
	public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
	//通过 transformedBeanName(name) 方法对给定的 bean 名称进行转换。
		String beanName = transformedBeanName(name);
		//通过 getSingleton(beanName, false) 方法尝试获取对应 beanName 的单例 Bean 实例,第二个参数 false 表示不创建新的 Bean 实例。
		Object beanInstance = getSingleton(beanName, false);
		if (beanInstance != null) {
		//如果获取到了单例 Bean 实例,判断该实例是否是 FactoryBean 的实例,如果是,则返回 true。
			return (beanInstance instanceof FactoryBean);
		}
		//如果没有获取到单例 Bean 实例,继续检查是否包含对应 beanName 的 BeanDefinition。
		if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
			//如果没有找到 Bean 定义,并且当前工厂的父工厂是 ConfigurableBeanFactory 的实例,那么委托父工厂来判断是否是 FactoryBean。
			return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
		}
		//如果父工厂也没有那么只能通过合并后的BeanDeniftion来判断
		return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
	}

	protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
	//首先,尝试从 mbd.isFactoryBean 缓存中获取结果。
		Boolean result = mbd.isFactoryBean;
		if (result == null) {
			// 根据BeanDefinition推测Bean类型(获取BeanDefinition的beanClass属性)
			Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
			// 判断是不是实现了FactoryBean接口
			result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
			mbd.isFactoryBean = result;
		}
		return result;
	}

总体来说,该方法的作用是判断给定的 bean 名称是否对应一个 FactoryBean。首先,尝试从单例实例中获取,然后检查是否包含 Bean 定义,最后通过合并的本地 Bean 定义来判断是否是 FactoryBean。如果都无法确定,则委托给父工厂(如果有的话)进行判断。如果当前是FacrotyBean,就会执行下面代码:

// 调用getBean方法将我们的FacrotyBean创建出来了
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
//创建一个FactoryBean
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
						//判断是不是实现了SmartFactoryBean接口,SmartFactoryBean是FactoryBean的实现类
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							// 创建真正的Bean对象(getObject()返回的对象)
							getBean(beanName);
						}
					}

如果当前bean不是FactoryBean,则直接执行 getBean(beanName) 方法。getBean(beanName) 方法执行完后,所有的非懒加载的单例bean都已经实例化完了,继续执行preInstantiateSingletons的逻辑

	// 所有的非懒加载单例Bean都创建完了后
		// Trigger post-initialization callback for all applicable beans...
		//再次遍历所有的beanName
		for (String beanName : beanNames) {
		//根据beanName在单例池中获取单例对象
			Object singletonInstance = getSingleton(beanName);
			//如果单例对象继承了SmartInitializingSingleton接口,表示该 Bean 需要在所有单例 Bean 创建完成后执行智能初始化回调。
			if (singletonInstance instanceof SmartInitializingSingleton) {
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
//调用该单例对象重写的afterSingletonsInstantiated方法
					smartSingleton.afterSingletonsInstantiated();
				}
				smartInitialize.end();
			}
		}

文章来源:https://blog.csdn.net/qq_43456605/article/details/135121713
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。