Spring源码 15 IOC refresh方法10
参考源
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 的核心是
AbstractApplicationContext
的refresh
方法。
其中一共有 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的更多相关文章
- Spring源码 07 IOC refresh方法2
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 18 IOC refresh方法13
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 16 IOC refresh方法11
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 17 IOC refresh方法12
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 14 IOC refresh方法9
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 11 IOC refresh方法6
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 09 IOC refresh方法4
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 08 IOC refresh方法3
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 06 IOC refresh方法1
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
随机推荐
- Mac 睡眠唤醒 不睡眠 问题
问题 之前一直有夜晚睡觉前电脑关机的习惯,主要是想着电脑也跟人一样️要休息.然后最近想着自己 Mac 干脆每天睡眠算了,省得每天开关机麻烦,所以就最近这段时间每次夜晚睡觉前主动去点了电脑的 「Slee ...
- 硬件开发笔记(四):硬件开发基本流程,制作一个USB转RS232的模块(三):设计原理图
前者 前面建立好的基础的元器件,下面开始设计原理图. 需求 USB转RS232,输出RS232 可以选择性输出5V的TTL 可以选择性输出3.3V的TTL 设计原理图 步骤一:CH340G ...
- 开发工具-RSA加解密
更新日志 2022年6月10日 初始化链接. https://toolb.cn/rsa
- 14.Nginx搭建及优化
Nginx搭建及优化 目录 Nginx搭建及优化 Nginx服务基础 概述 Nginx和Apache的优缺点比较 编译安装Nginx服务 添加Nginx系统服务 Nginx服务配置文件 nginx服务 ...
- Spring Security认证器实现
目录 拦截请求 验证过程 返回完整的Authentication 收尾工作 结论 一些权限框架一般都包含认证器和决策器,前者处理登陆验证,后者处理访问资源的控制 Spring Security的登陆请 ...
- SAP setting and releasing locks
REPORT demo_transaction_enqueue MESSAGE-ID sabapdocu. TABLES sflight. DATA text(8) TYPE c. DATA ok_c ...
- 解决github.com 的响应时间过长以及hosts配置不能保存的问题
github.com 的响应时间过长 1 获取github可以使用的DNS域名 DNS查询 选择TTL值最小的 2 修改hosts配置 打开之后在最后加上如下内容,保存即可 3 出现hosts不能保存 ...
- go语言学习笔记-初识Go语言
Go语言是怎样诞生的? Go语言的创始人有三位,分别是图灵奖获得者.C语法联合发明人.Unix之父肯·汤普森(Ken Thompson).Plan 9操作系统领导者.UTF-8编码的最初设计者罗伯·派 ...
- 感知器网络(MP模型)和自适应线性元件
- HMS Core安全检测服务如何帮助大学新生防范电信诈骗?
一年一度的高考结束了,很多学生即将离开父母,一个人踏入大学生活,但由于人生阅历较少,容易被不法分子盯上. 每年开学季也是大一新生遭受诈骗的高峰期,以下是一些常见的案例.有的骗子会让新生下载注册一些恶意 ...