当前位置: 首页 > java >正文

Spring的源码Spring的上下文怎么存储

Spring框架是一个广泛使用的Java框架,它提供了丰富的功能,包括依赖注入(DI)、面向切面编程(AOP)、事务管理等。而在Spring的核心功能之一——ApplicationContext,它负责管理和配置Spring的bean容器。ApplicationContext 是 Spring 容器的顶级接口,它继承自 BeanFactory,并提供了更多的功能,比如事件传播、国际化支持等。

Spring上下文的存储

Spring的上下文主要通过BeanFactoryApplicationContext 来存储和管理Bean。ApplicationContextBeanFactory 的一个扩展,提供了更多的功能。Spring的上下文一般是通过读取配置文件(如XML或注解)来初始化Bean定义的,并将它们存储在容器中。具体来说,ApplicationContext 通过以下方式存储 Bean:

  1. Bean Definition:存储了Bean的定义(即Bean的名称、类、作用域等信息)。
  2. Bean 实例:存储了Bean的实例,当Bean被请求时,ApplicationContext 会根据其配置创建并返回一个Bean的实例。
  3. BeanFactory的实现ApplicationContext 内部实现了对 BeanFactory 的扩展,管理着一个 Bean 的注册表。

Spring的上下文通常会创建一个类似 ConcurrentHashMap 的容器来存储这些bean定义和实例。具体实现取决于 Spring 中的 BeanFactoryApplicationContext 的实现类。

Spring 上下文存储代码示例

1. 使用注解配置 Spring Bean

假设你在一个 Spring Boot 或 Spring 项目中使用注解来配置 Bean:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Beanpublic MyBean myBean() {return new MyBean();}
}

在这个配置类中,@Configuration 注解表示这是一个配置类,@Bean 注解用于定义一个 Bean。Spring 会自动扫描这个类,并将 myBean 方法返回的实例注册为一个 Bean。

2. ApplicationContext 的实现和存储

Spring 容器通过 ApplicationContext 来管理这些 Bean。例如,AnnotationConfigApplicationContextApplicationContext 的一个实现,它用于基于注解的配置。

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Main {public static void main(String[] args) {// 创建 AnnotationConfigApplicationContext 容器并加载配置类ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);// 获取 myBean 实例MyBean myBean = context.getBean(MyBean.class);System.out.println(myBean);}
}
3. Spring Bean 存储的实现

AnnotationConfigApplicationContext 中,ApplicationContext 会通过 DefaultListableBeanFactory(它是 BeanFactory 的一个实现)来存储和管理 Bean。Spring 的 DefaultListableBeanFactory 会维护一个 Map 来存储这些 Bean 定义(BeanDefinition),然后再通过这些定义来创建 Bean 实例。

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.support.GenericApplicationContext;public class SpringContextStorageExample {public static void main(String[] args) {GenericApplicationContext context = new GenericApplicationContext();context.register(AppConfig.class); // 注册配置类context.refresh(); // 刷新上下文,初始化 bean// 获取 bean 实例MyBean myBean = context.getBean(MyBean.class);System.out.println(myBean);}
}
4. DefaultListableBeanFactory 中的存储

Spring会将bean的定义存储在一个叫做 DefaultListableBeanFactory 的类中,该类实现了 BeanFactoryBeanDefinitionRegistry 接口。

public class DefaultListableBeanFactory extends AbstractBeanFactory implements BeanDefinitionRegistry {private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {beanDefinitionMap.put(beanName, beanDefinition);}@Overridepublic BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {return beanDefinitionMap.get(beanName);}// 通过BeanDefinition创建bean实例public Object getBean(String name) throws BeansException {BeanDefinition beanDefinition = getBeanDefinition(name);return createBean(beanDefinition);}
}
  • beanDefinitionMap 是一个 ConcurrentHashMap,用来存储 BeanDefinition
  • BeanDefinition 存储了一个 Bean 的定义信息(例如 Bean 的类类型、构造方法等),DefaultListableBeanFactory 会根据这些定义来创建和管理 Bean 实例。
5. Bean 实例化和缓存

getBean() 方法被调用时,Spring 会检查这个 Bean 是否已经创建过。如果已经创建过,Spring 会直接从缓存中返回这个实例。Spring 容器对每个 Bean 使用不同的作用域进行管理,默认是单例模式。

public class DefaultListableBeanFactory {private final Map<String, Object> singletonCache = new ConcurrentHashMap<>();public Object getBean(String name) {// 检查缓存中是否已经有这个 Bean 实例if (singletonCache.containsKey(name)) {return singletonCache.get(name);}// 如果没有,创建新的实例BeanDefinition beanDefinition = getBeanDefinition(name);Object bean = createBean(beanDefinition);// 将实例缓存到 singletonCache 中singletonCache.put(name, bean);return bean;}
}

总结

Spring 上下文的存储本质上是通过 ApplicationContext(具体实现类如 AnnotationConfigApplicationContext)来管理 Bean 的定义和实例。ApplicationContext 使用 BeanFactory 来管理 Bean 定义(如 BeanDefinition)和实例化,并通过缓存机制来优化性能。Spring 通过不同的 BeanFactory 实现(如 DefaultListableBeanFactory)来存储、创建和缓存 Bean。

以上示例展示了 Spring 是如何通过容器存储和管理 Bean 的,ApplicationContextBeanFactory 的实现内部细节以及它们如何通过 Map 结构来管理这些对象。

http://www.xdnf.cn/news/3220.html

相关文章:

  • Electron Forge【实战】自定义菜单 -- 顶部菜单 vs 右键快捷菜单
  • 百度网盘golang实习面经
  • HTML from表单中只有一个input时,按回车键后表单自动提交(form表单的一个小坑)
  • 【C++】频繁分配和释放会产生内存碎片
  • Win下的Kafka安装配置
  • Tauri v1 与 v2 配置对比
  • 全面解析SimHash算法:原理、对比与Spring Boot实践指南
  • transformer-实现解码器Decoder
  • DIT(Diffusion In Transformer)学习笔记
  • Java继承中super的使用方法
  • SI5338-EVB Usage Guide(LVPECL、LVDS、HCSL、CMOS、SSTL、HSTL)
  • 电子病历高质量语料库构建方法与架构项目(智能数据目录篇)
  • SD - WAN 跨境网络专线部署方式介绍
  • 大数据在远程医疗中的创新应用:如何重塑医疗行业的未来
  • python + segno 生成个人二维码
  • 全球气象站点年平均降水数据(1929-2024)
  • 大连理工大学选修课——机器学习笔记(4):NBM的原理及应用
  • 大连理工大学选修课——机器学习笔记(9):线性判别式与逻辑回归
  • 使用 ossutil 上传文件到阿里云 OSS
  • 基于连接感知的实时困倦分类图神经网络
  • 【数学】角谷猜想
  • 服务器热备份,服务器热备份的方法有哪些?
  • 猿人学web端爬虫攻防大赛赛题第13题——入门级cookie
  • 完美解决react-native文件直传阿里云oss问题一
  • Android学习总结之自定义view设计模式理解
  • Redis热key大key详解
  • ESP32开发-通过ENC28J60模块实现以太网设备
  • 从实列中学习linux shell6: 写一个 shell 脚本 过滤 恶意ip 攻击
  • css 数字从0开始增加的动画效果
  • 【数学建模国奖速成系列】优秀论文绘图复现代码(二)