参考源

https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click

https://www.bilibili.com/video/BV12Z4y197MU?spm_id_from=333.999.0.0

《Spring源码深度解析(第2版)》

版本

本文章基于 Spring 5.3.15


Spring IOC 的核心是 AbstractApplicationContextrefresh 方法。

其中一共有 13 个主要方法,这里分析第 10 个:registerListeners

1 AbstractApplicationContext

1-1 注册监听器

registerListeners()
protected void registerListeners() {
// 获取应用程序监听器。硬编码方法注册的监听器处理
for (ApplicationListener<?> listener : getApplicationListeners()) {
// 获取应用程序事件多播器
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 配置文件注册的监听器处理
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
// 获取应用程序事件多播器
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
// 多播事件
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}

1-2 获取应用程序监听器

getApplicationListeners()
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();

public Collection<ApplicationListener<?>> getApplicationListeners() {
return this.applicationListeners;
}

1-2 获取应用程序事件多播器

getApplicationEventMulticaster()
ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
if (this.applicationEventMulticaster == null) {
throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +
"call 'refresh' before multicasting events via the context: " + this);
}
return this.applicationEventMulticaster;
}

由于前面注册了多播器,这里直接返回。

1-2 配置文件注册的监听器

getBeanNamesForType(ApplicationListener.class, true, false)
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
// 断言 Bean 工厂活动
assertBeanFactoryActive();
// 返回与给定类型匹配的 bean 的名称
return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
}

1-3 断言 Bean 工厂活动

assertBeanFactoryActive()
protected void assertBeanFactoryActive() {
if (!this.active.get()) {
if (this.closed.get()) {
// 获取显示名称
throw new IllegalStateException(getDisplayName() + " has been closed already");
}
else {
// 获取显示名称
throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
}
}
}

1-4 获取显示名称

private String displayName = ObjectUtils.identityToString(this);

public String getDisplayName() {
return this.displayName;
}

1-3 返回与给定类型匹配的 bean 的名称

getBeanNamesForType(type, includeNonSingletons, allowEagerInit)

2 DefaultListableBeanFactory

public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
// 判断是否配置冻结
if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
// 进一步返回与给定类型匹配的 bean 的名称
return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
}
Map<Class<?>, String[]> cache =
(includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
String[] resolvedBeanNames = cache.get(type);
if (resolvedBeanNames != null) {
return resolvedBeanNames;
}
// 进一步返回与给定类型匹配的 bean 的名称
resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
cache.put(type, resolvedBeanNames);
}
return resolvedBeanNames;
}

2-1 判断是否配置冻结

isConfigurationFrozen()
private volatile boolean configurationFrozen;

public boolean isConfigurationFrozen() {
return this.configurationFrozen;
}

2-1 进一步返回与给定类型匹配的 bean 的名称

doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit)
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
List<String> result = new ArrayList<>(); // Check all bean definitions.
// 检查所有的 Bean 定义信息
for (String beanName : this.beanDefinitionNames) {
// Only consider bean as eligible if the bean name is not defined as alias for some other bean.
// 是否别名。如果 bean 名称未定义为其他 bean 的别名,则将 bean 视为合格
if (!isAlias(beanName)) {
try {
// 获取合并的本地 Bean 定义信息
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Only check bean definition if it is complete.
if (!mbd.isAbstract() && (allowEagerInit ||
(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
boolean isFactoryBean = isFactoryBean(beanName, mbd);
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
boolean matchFound = false;
boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));
boolean isNonLazyDecorated = (dbd != null && !mbd.isLazyInit());
if (!isFactoryBean) {
if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
else {
if (includeNonSingletons || isNonLazyDecorated ||
(allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
if (!matchFound) {
// In case of FactoryBean, try to match FactoryBean instance itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
if (matchFound) {
result.add(beanName);
}
}
}
catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {
if (allowEagerInit) {
throw ex;
}
// Probably a placeholder: let's ignore it for type matching purposes.
LogMessage message = (ex instanceof CannotLoadBeanClassException ?
LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) :
LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName));
logger.trace(message, ex);
// Register exception, in case the bean was accidentally unresolvable.
// 注册异常,以防 bean 意外无法解析
onSuppressedException(ex);
}
catch (NoSuchBeanDefinitionException ex) {
// Bean definition got removed while we were iterating -> ignore.
}
}
} // Check manually registered singletons too.
for (String beanName : this.manualSingletonNames) {
try {
// In case of FactoryBean, match object created by FactoryBean.
// 判断是否是工厂 Bean
if (isFactoryBean(beanName)) {
if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
result.add(beanName);
// Match found for this bean: do not match FactoryBean itself anymore.
continue;
}
// In case of FactoryBean, try to match FactoryBean itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
}
// Match raw bean instance (might be raw FactoryBean).
// 判断是否是类型匹配
if (isTypeMatch(beanName, type)) {
result.add(beanName);
}
}
catch (NoSuchBeanDefinitionException ex) {
// Shouldn't happen - probably a result of circular reference resolution...
logger.trace(LogMessage.format(
"Failed to check manually registered singleton with name '%s'", beanName), ex);
}
} return StringUtils.toStringArray(result);
}

2-2 是否别名

isAlias(beanName)

3 SimpleAliasRegistry

private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);

public boolean isAlias(String name) {
return this.aliasMap.containsKey(name);
}

2 DefaultListableBeanFactory

2-2 获取合并的本地 Bean 定义信息

getMergedLocalBeanDefinition(beanName)

4 AbstractBeanFactory

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
return mbd;
}
// 获取合并的 Bean 定义信息
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
// 获取合并的 Bean 定义信息
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;
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null || mbd.stale) {
previous = mbd;
if (bd.getParentName() == null) {
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
} else {
mbd = new RootBeanDefinition(bd);
}
} else {
BeanDefinition pbd;
try {
// 转换 Bean 名称
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
// 获取合并的 Bean 定义信息
pbd = getMergedBeanDefinition(parentBeanName);
} else {
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
// 获取合并的 Bean 定义信息
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);
}
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
// 复制合并相关的 Bean 定义缓存
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
return mbd;
}
}

4-1 转换 Bean 名称

transformedBeanName(bd.getParentName())
protected String transformedBeanName(String name) {
// 转换 Bean 名称
// 规范名称
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

4-2 转换 Bean 名称

transformedBeanName(name)

5 BeanFactoryUtils

public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}

4 AbstractBeanFactory

4-2 规范名称

canonicalName(BeanFactoryUtils.transformedBeanName(name))
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}

4-1 获取合并的 Bean 定义信息

getMergedBeanDefinition(parentBeanName)
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
String beanName = transformedBeanName(name);
// Efficiently check whether bean definition exists in this factory.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
}
// Resolve merged bean definition locally.
// 获取合并的 Bean 定义信息
return getMergedLocalBeanDefinition(beanName);
}

4-2 获取合并的本地 Bean 定义信息

getMergedLocalBeanDefinition(beanName)
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) {
return mbd;
}
// 获取合并的 Bean 定义信息
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

4-3 获取合并的 Bean 定义信息

getMergedBeanDefinition(beanName, getBeanDefinition(beanName))
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd) throws BeanDefinitionStoreException {
// 获取合并的 Bean 定义信息
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;
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null || mbd.stale) {
previous = mbd;
if (bd.getParentName() == null) {
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
} else {
mbd = new RootBeanDefinition(bd);
}
} else {
BeanDefinition pbd;
try {
// 转换 Bean 名称
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
// 获取合并的 Bean 定义信息
pbd = getMergedBeanDefinition(parentBeanName);
} else {
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
// 获取合并的 Bean 定义信息
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);
}
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
// 复制合并相关的 Bean 定义缓存
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
return mbd;
}
}

这里递归调用又回到了前面的方法。直到 if (!beanName.equals(parentBeanName)) 不再满足,即不再包含父类。

4-1 复制合并相关的 Bean 定义缓存

copyRelevantMergedBeanDefinitionCaches(previous, mbd)
private void copyRelevantMergedBeanDefinitionCaches(RootBeanDefinition previous, RootBeanDefinition mbd) {
if (ObjectUtils.nullSafeEquals(mbd.getBeanClassName(), previous.getBeanClassName()) &&
ObjectUtils.nullSafeEquals(mbd.getFactoryBeanName(), previous.getFactoryBeanName()) &&
ObjectUtils.nullSafeEquals(mbd.getFactoryMethodName(), previous.getFactoryMethodName())) {
ResolvableType targetType = mbd.targetType;
ResolvableType previousTargetType = previous.targetType;
if (targetType == null || targetType.equals(previousTargetType)) {
mbd.targetType = previousTargetType;
mbd.isFactoryBean = previous.isFactoryBean;
mbd.resolvedTargetType = previous.resolvedTargetType;
mbd.factoryMethodReturnType = previous.factoryMethodReturnType;
mbd.factoryMethodToIntrospect = previous.factoryMethodToIntrospect;
}
}
}

Spring源码 15 IOC refresh方法10的更多相关文章

  1. Spring源码 07 IOC refresh方法2

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  2. Spring源码 18 IOC refresh方法13

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  3. Spring源码 16 IOC refresh方法11

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  4. Spring源码 17 IOC refresh方法12

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  5. Spring源码 14 IOC refresh方法9

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  6. Spring源码 11 IOC refresh方法6

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  7. Spring源码 09 IOC refresh方法4

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  8. Spring源码 08 IOC refresh方法3

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  9. Spring源码 06 IOC refresh方法1

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

随机推荐

  1. 博弈论(nim游戏,SG函数)

    说到自己,就是个笑话.思考问题从不清晰,sg函数的问题证明方法就在眼前可却要弃掉.不过自己理解的也并不透彻,做题也不太行.耳边时不时会想起alf的:"行不行!" 基本的小概念 这里 ...

  2. AcWing 1248. 灵能传输 蓝桥杯

    蓝桥杯的一道题:灵能传输 https://www.acwing.com/problem/content/description/1250/ 首先是简化操作,将原数组转化为前缀和数组(下标都是从1开始) ...

  3. PostgreSQL 13支持增量排序(Incremental Sorting)

    PostgreSQL 13支持增量排序(Incremental Sorting) PostgreSQL 13一个重要的功能是支持增量排序,使用order by 时可以加速排序,SQL如下 select ...

  4. CabloyJS 4.12震撼发布,及新版教程尝鲜

    引言 凡是可以用 JavaScript 来写的应用,最终都会用 JavaScript 来写 | Atwood 定律 目前市面上出现的大多数与 NodeJS 相关的框架,基本都将 NodeJS 定位在工 ...

  5. Python列表推导式,字典推导式,元组推导式

    参考:https://blog.csdn.net/A_Tu_daddy/article/details/105051821 my_list = [ [[1, 2, 3], [4, 5, 6]] ] f ...

  6. bare Git 仓库是什么?

    背景 今天,坐我旁边的同事问我一些关于服务器上命令的问题.其中有一个用了特殊参数的 git init 的命令,我也不认识,遂去 Google... bare Git 仓库 定义 A bare Git ...

  7. 开发工具-Redis Desktop Manager下载地址

    更新记录 2022年6月10日 完善标题. 官方: https://github.com/uglide/RedisDesktopManager 免费打包版: https://github.com/le ...

  8. .NET中检测文件是否被其他进程占用

    更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月2日. 一.检测文件是否被进程占用的几种方式 在.NET中主要有以下方式进行检测文件是否被进程占用的几种方式: 通过直接打开文件等 ...

  9. BUUCTF-假如给我三天光明

    假如给我三天光明 打开压缩包可以看到一个海报,下方有盲文显示,通过对照表得知 盲文翻译为kmdonowg 通过盲文翻译得到的字符串解压压缩包得到一个音频文件 使用Audacity打开,看样子应该是摩斯 ...

  10. 关于kali安装输入法

    之前老是被kali大小写输入恶心坏了,正好看到一篇文章写kali安装搜狗输入法的,虽然不需要输入中文,但是英文输入就很方便了. 一.切换root用户登录 1.sodu su切换为root权限 2.pa ...