本文章基于 Spring 5.3.15
Spring IOC 的核心是
其中一共有 13 个主要方法,这里分析第 7 个:AbstractApplicationContext
的refresh
方法。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 SetalreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));protected boolean hasBeanCreationStarted() { return !this.alreadyCreated.isEmpty();}
3-1 按类型清除缓存
clearByTypeCache()
private void clearByTypeCache() { this.allBeanNamesByType.clear(); this.singletonBeanNamesByType.clear();}