Bean生命周期源码(一)
一. 简介
Spring最重要的功能就是帮助程序员创建对象(也就是IOC),而Spring就是为创建Bean对象做准备,所以我们需要先搞明白Spring到底是如何创建Bean的,也就是先弄明白Bean的生命周期。
二. Bean的生成过程
1. 容器启动
在生成Bean之前,我们首先需要将容器启动起来。启动容器主要做两件事:
- 扫描指定路径下的类
- 创建非懒加载的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.zhouyu
,ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
为classpath*:
,然后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();
}
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!