博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring源码 12 IOC refresh方法7
阅读量:37194 次
发布时间:2020-08-01

本文共 4785 字,大约阅读时间需要 15 分钟。

本文章基于 Spring 5.3.15

Spring IOC 的核心是 AbstractApplicationContextrefresh 方法。

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

1 AbstractApplicationContext

1-1 初始化 message 源

initMessageSource()
protected void initMessageSource() {   // 获取 Bean 工厂   ConfigurableListableBeanFactory beanFactory = getBeanFactory();   if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {      // 如果在配置中已经配置了 messageSource,那么将 messageSource 提取并记录在 this.messageSource 中      this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);      if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {         HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;         if (hms.getParentMessageSource() == null) {            hms.setParentMessageSource(getInternalParentMessageSource());         }      }      if (logger.isTraceEnabled()) {         logger.trace("Using MessageSource [" + this.messageSource + "]");      }   } else {      // 如果用户并没有定义配置文件,那么使用临时的 DelegatingMessageSource 以便于作为调用 getMessage 方法的返回      DelegatingMessageSource dms = new DelegatingMessageSource();      dms.setParentMessageSource(getInternalParentMessageSource());      this.messageSource = dms;      // 注册单例      beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);      if (logger.isTraceEnabled()) {         logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");      }   }}

1-2 获取 Bean 工厂

getBeanFactory()

2 AbstractRefreshableApplicationContext

public final ConfigurableListableBeanFactory getBeanFactory() {   DefaultListableBeanFactory beanFactory = this.beanFactory;   if (beanFactory == null) {      throw new IllegalStateException("BeanFactory not initialized or already closed - " + "call 'refresh' before accessing beans via the ApplicationContext");   }   return beanFactory;}

if (beanFactory == null) 由于 beanFactory 已经被赋值,直接返回。

1 AbstractApplicationContext

1-2 注册单例

registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource)

3 DefaultListableBeanFactory

public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {   // 调用父类方法   super.registerSingleton(beanName, singletonObject);   // 手动更新单例名称   updateManualSingletonNames(set -> set.add(beanName), set -> !this.beanDefinitionMap.containsKey(beanName));   // 按类型清除缓存   clearByTypeCache();}

3-1 调用父类方法

super.registerSingleton(beanName, singletonObject)

4 DefaultSingletonBeanRegistry

public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {   Assert.notNull(beanName, "Bean name must not be null");   Assert.notNull(singletonObject, "Singleton object must not be null");   synchronized (this.singletonObjects) {      Object oldObject = this.singletonObjects.get(beanName);      if (oldObject != null) {         throw new IllegalStateException("Could not register object [" + singletonObject +               "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");      }      // 添加单例      addSingleton(beanName, singletonObject);   }}

4-1 添加单例

addSingleton(beanName, singletonObject)
protected void addSingleton(String beanName, Object singletonObject) {   synchronized (this.singletonObjects) {      this.singletonObjects.put(beanName, singletonObject);      this.singletonFactories.remove(beanName);      this.earlySingletonObjects.remove(beanName);      this.registeredSingletons.add(beanName);   }}

3 DefaultListableBeanFactory

3-1 手动更新单例名称

updateManualSingletonNames(set -> set.add(beanName), set -> !this.beanDefinitionMap.containsKey(beanName))
private void updateManualSingletonNames(Consumer
> action, Predicate
> condition) { // 如果已开始创建 Bean if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { if (condition.test(this.manualSingletonNames)) { Set
updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames); action.accept(updatedSingletons); this.manualSingletonNames = updatedSingletons; } } } else { // Still in startup registration phase if (condition.test(this.manualSingletonNames)) { action.accept(this.manualSingletonNames); } }}

3-2 判断是否已开始创建 Bean

private final Set
alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));protected boolean hasBeanCreationStarted() { return !this.alreadyCreated.isEmpty();}

3-1 按类型清除缓存

clearByTypeCache()
private void clearByTypeCache() {   this.allBeanNamesByType.clear();   this.singletonBeanNamesByType.clear();}

转载地址:http://hupwwy.baihongyu.com/

你可能感兴趣的文章
Intellij IDEA使用(三)——在Intellij IDEA中配置Tomcat服务器
查看>>
Intellij IDEA使用(四)—— 使用Intellij IDEA创建静态的web(HTML)项目
查看>>
Intellij IDEA使用(五)—— Intellij IDEA在使用中的一些其他常用功能或常用配置收集
查看>>
Intellij IDEA使用(六)—— 使用Intellij IDEA创建Java项目并配置jar包
查看>>
Eclipse使用(十)—— 使用Eclipse创建简单的Maven Java项目
查看>>
Eclipse使用(十一)—— 使用Eclipse创建简单的Maven JavaWeb项目
查看>>
Intellij IDEA使用(十三)—— 在Intellij IDEA中配置Maven
查看>>
面试题 —— 关于main方法的十个面试题
查看>>
集成测试(一)—— 使用PHP页面请求Spring项目的Java接口数据
查看>>
使用Maven构建的简单的单模块SSM项目
查看>>
Intellij IDEA使用(十四)—— 在IDEA中创建包(package)的问题
查看>>
FastDFS集群架构配置搭建(转载)
查看>>
HTM+CSS实现立方体图片旋转展示效果
查看>>
FFmpeg 命令操作音视频
查看>>
问题:Opencv(3.1.0/3.4)找不到 /opencv2/gpu/gpu.hpp 问题
查看>>
目的:使用CUDA环境变量CUDA_VISIBLE_DEVICES来限定CUDA程序所能使用的GPU设备
查看>>
问题:Mysql中字段类型为text的值, java使用selectByExample查询为null
查看>>
程序员--学习之路--技巧
查看>>
解决问题之 MySQL慢查询日志设置
查看>>
contOS6 部署 lnmp、FTP、composer、ThinkPHP5、docker详细步骤
查看>>