Spring源码分析(BeanFactory)

文章目录

  • Spring源码分析(BeanFactory)
  • 一、BeanFactory
  • 二、ApplicationContext 的父系
    • 1、HierarchicalBeanFactory
    • 2、ListableBeanFactory
    • 3、EnvironmentCapable
    • 4、ApplicationEventPublisher
    • 5、MessageSource
    • 6、ResourcePatternResolver
  • 三、ApplicationContext 的实现
  • 四、BeanFactory的创建
    • 1、Spring中的创建
    • 2、SpringBoot中的创建
  • 五、DefaultListableBeanFactory
    • 1、为什么选择 DefaultListableBeanFactory?
    • 2、运行时获取 DefaultListableBeanFactory

Spring源码分析(BeanFactory)

在这里插入图片描述

一、BeanFactory

BeanFactory最顶层的容器接口,只提供了获取Bean相关的一些方法。

public interface BeanFactory {// 对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象String FACTORY_BEAN_PREFIX = "&";// 根据bean的名字,在IOC容器中得到bean实例,Object getBean(String name) throws BeansException;// 根据bean的名字,在IOC容器中得到bean实例,args:显式参数(必须为非单例模式)Object getBean(String name, Object... args) throws BeansException;// 根据bean的名字获得对象,并转换为Class类型(可以不用进行类型转换)<T> T getBean(String name, Class<T> requiredType);// 根据bean的类型获得对象(必须是拥有唯一实现类)<T> T getBean(Class<T> requiredType) throws BeansException;// 根据bean的类型获得对象,args:显式参数<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;// 判断IOC容器是否有这个名字的beanboolean containsBean(String name);// 判断这个bean是不是单例 boolean isSingleton(String name) throws NoSuchBeanDefinitionException;// 判断这个bean是不是多例 boolean isPrototype(String name) throws NoSuchBeanDefinitionException;// 获取bean实例的Class类型  Class<?> getType(String name) throws NoSuchBeanDefinitionException;// 这里得到bean的别名,如果根据别名检索,那么其原名也会被检索出来  String[] getAliases(String name);
}

二、ApplicationContext 的父系

ApplicationContext是更高级的容器接口,继承了许多其他接口,提供了更多的功能。

  • 获取 Environment(EnvironmentCapable)
  • getBean 的扩展(ListableBeanFactory)
  • 事件的发布与监听机制(ApplicationEventPublisher)
  • 支持父子容器(HierarchicalBeanFactory)
  • 国际化(MessageSource)
  • 事件的发布与监听机制(ApplicationEventPublisher)
  • 资源访问(ResourcePatternResolver)
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {@NullableString getId();String getApplicationName();String getDisplayName();long getStartupDate();@NullableApplicationContext getParent();// 用于进行手动的 Bean 注入和依赖注入AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;}

1、HierarchicalBeanFactory

HierarchicalBeanFactory 用于表示具有层次结构的 BeanFactory 容器。

  • 支持父子容器的关系,一个 BeanFactory 可以有一个或多个父容器。

    子容器可以访问父容器中定义的 Bean,但父容器不能访问子容器中定义的 Bean。

  • 如果子容器中不存在某个 Bean,则会委托父容器进行查找。

public interface HierarchicalBeanFactory extends BeanFactory {@NullableBeanFactory getParentBeanFactory();boolean containsLocalBean(String name);
}

2、ListableBeanFactory

ListableBeanFactory 扩展了 BeanFactory 接口,提供了额外的功能来 获取 Bean 及其相关信息

public interface ListableBeanFactory extends BeanFactory {// 获取 Bean 的定义信息boolean containsBeanDefinition(String beanName);int getBeanDefinitionCount();String[] getBeanDefinitionNames();// 通过 类型 获取 BeanString[] getBeanNamesForType(ResolvableType type);String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);String[] getBeanNamesForType(@Nullable Class<?> type);String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);// 通过 注解 获取BeanString[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);// 获取 <beanName, type><T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException;// 获取 <beanName, annotation>Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;// 获取bean的注解@Nullable<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)throws NoSuchBeanDefinitionException;
}

3、EnvironmentCapable

EnvironmentCapable 接口用于获取 Environment 实例

public interface EnvironmentCapable {Environment getEnvironment();
}

Environment 用于表示运行时环境(例如配置文件、系统属性、环境变量等)的抽象,提供了访问应用程序配置信息的统一接口。

public interface Environment extends PropertyResolver {// 返回激活profile名称的数组String[] getActiveProfiles();// 返回默认profile名称的数组String[] getDefaultProfiles();// environment是否支持给定profileboolean acceptsProfiles(Profiles profiles);@Deprecated // 弃用boolean acceptsProfiles(String... profiles);
}
public interface PropertyResolver {// 检查某个属性是否存在boolean containsProperty(String key);// 获取指定属性的值(不存在则返回null)String getProperty(String key);// 获取指定属性的值(不存在则返回默认值)String getProperty(String key, String defaultValue);// 获取指定属性的值,可以指定要返回对象的类型(不存在则返回null)<T> T getProperty(String key, Class<T> targetType);// 获取指定属性的值,可以指定要返回对象的类型(不存在则返回默认值)<T> T getProperty(String key, Class<T> targetType, T defaultValue);// 获取指定属性的值(不存在则抛出异常)String getRequiredProperty(String key) throws IllegalStateException;<T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException;String resolvePlaceholders(String text);String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;
}

4、ApplicationEventPublisher

ApplicationEventPublisher 用于发布应用程序事件并通知所有已注册的事件监听器

@FunctionalInterface
public interface ApplicationEventPublisher {default void publishEvent(ApplicationEvent event) {publishEvent((Object) event);}void publishEvent(Object event);
}

5、MessageSource

MessageSource 是 Spring Framework 中用于国际化支持的接口之一。

  • 它提供了一种统一的方式来访问应用程序中的消息资源,支持多语言和多地区的国际化功能。
public interface MessageSource {String getMessage(String code, Object[] args, String defaultMessage, Locale locale);String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}

6、ResourcePatternResolver

ResourcePatternResolver 加载和访问应用程序中的资源,支持通配符和模式匹配,可以方便地加载多个资源。

public interface ResourcePatternResolver extends ResourceLoader {String CLASSPATH_ALL_URL_PREFIX = "classpath*:";Resource[] getResources(String var1) throws IOException;
}
public interface ResourceLoader {String CLASSPATH_URL_PREFIX = "classpath:";Resource getResource(String var1);@NullableClassLoader getClassLoader();
}

三、ApplicationContext 的实现

ApplicationContext 负责创建和管理应用程序中的所有 Bean 对象,其实现类的区别仅仅在于如何加载配置

在这里插入图片描述

  • AnnotationConfigApplicationContext:使用「注解方式」加载配置
  • ClassPathXmlApplicationContext:从「资源根目录」下加载配置
  • FileSystemXmlApplicationContext:从「文件路径下」加载配置

四、BeanFactory的创建

1、Spring中的创建

// org.springframework.context.support.AbstractApplicationContext@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// ...ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// ...}
}
// org.springframework.context.support.AbstractApplicationContextprotected ConfigurableListableBeanFactory obtainFreshBeanFactory() {// 刷新 BeanFactory(关闭旧的,创建新的)refreshBeanFactory();// 返回 BeanFactoryreturn getBeanFactory();
}
// org.springframework.context.support.AbstractRefreshableApplicationContext@Override
protected final void refreshBeanFactory() throws BeansException {// ...try {// 创建 DefaultListableBeanFactoryDefaultListableBeanFactory beanFactory = createBeanFactory();// ...} catch (IOException ex) {throw new ApplicationContextException(...., ex);}
}protected DefaultListableBeanFactory createBeanFactory() {return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}

可以看到,创建的 BeanFactory 是 DefaultListableBeanFactory

2、SpringBoot中的创建

@SpringBootApplication
public class BasicProjectApplication {public static void main(String[] args) {SpringApplication.run(BasicProjectApplication.class, args);}
}
// org.springframework.boot.SpringApplicationpublic static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {return run(new Class[]{primarySource}, args);
}public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {// 构建 SpringApplication实例 并执行run方法return (new SpringApplication(primarySources)).run(args);
}public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {return (new SpringApplication(primarySources)).run(args);
}public ConfigurableApplicationContext run(String... args) {// Spring容器ConfigurableApplicationContext context = null;try {// 构建Spring容器context = this.createApplicationContext();} // ...
}protected ConfigurableApplicationContext createApplicationContext() {Class<?> contextClass = this.applicationContextClass;if (contextClass == null) {try {switch (this.webApplicationType) {case SERVLET:// AnnotationConfigServletWebServerApplicationContextcontextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);break;case REACTIVE:// AnnotationConfigReactiveWebServerApplicationContextcontextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);break;default:// AnnotationConfigApplicationContextcontextClass = Class.forName(DEFAULT_CONTEXT_CLASS);}}catch (ClassNotFoundException ex) {throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);}}// 构建IoC容器return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}

可以看到,三种 contextClass 都是 GenericApplicationContext 的子类

在这里插入图片描述

在实例化之前,会先进行父类 GenericApplicationContext 的初始化

// org.springframework.context.support.GenericApplicationContextpublic GenericApplicationContext() {this.beanFactory = new DefaultListableBeanFactory();
}

可以看到,创建的 BeanFactory 是 DefaultListableBeanFactory

五、DefaultListableBeanFactory

1、为什么选择 DefaultListableBeanFactory?

为什么创建的 BeanFactory 要选择 DefaultListableBeanFactory 呢?

分析一下继承图:

在这里插入图片描述

可以看到:

  • ConfigurableListableBeanFactory 只有一个实现类 DefaultListableBeanFactory
  • DefaultListableBeanFactory 还通过实现右边的 AbstractAutowireCapableBeanFactory 通吃了右路

因此,DefaultListableBeanFactory 基本上是最牛的 BeanFactory 了,这也是为什么会选择实例化这个类的原因。

2、运行时获取 DefaultListableBeanFactory

如何在运行时获取 DefaultListableBeanFactory 实例呢?

  1. getAutowireCapableBeanFactory 获取 AutowireCapableBeanFactory
  2. AutowireCapableBeanFactory 向下转型得到 DefaultListableBeanFactory
public class GetDefaultListableBeanFactory {public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext();DefaultListableBeanFactory autowireCapableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/789194.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

了解这些技术:Flutter应用顺利登陆iOS平台的步骤与方法

引言 &#x1f680; Flutter作为一种跨平台的移动应用程序开发框架&#xff0c;为开发者提供了便利&#xff0c;使他们能够通过单一的代码库构建出高性能、高保真度的应用程序&#xff0c;同时支持Android和iOS两个平台。然而&#xff0c;完成Flutter应用程序的开发只是第一步…

【鹅厂摸鱼日记(一)】(工作篇)认识八大技术架构

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:重生之我在鹅厂摸鱼⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多知识   &#x1f51d;&#x1f51d; 认识八大架构 1. 前言2. 架构简介&…

【Spring】SpringBoot整合ShardingSphere并实现多线程分批插入10000条数据(进行分库分表操作)。

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 一、ShardingSphere简介 ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈&#xff0c;它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar&#xff08;计划中&#xff09;这3款相互独立的产品组成…

【2024 信息素养大赛c++模拟题】算法创意实践挑战赛(基于 C++)

一、 比赛简介 国务院发布《国务院关于印发新一代人工智能发展规划的通 知》&#xff0c;明确实施全民智能教育项目。教育部印发《2019 年教育信息 化和网络安全工作要点》&#xff0c;推动在中小学阶段设置人工智能相关课 程&#xff0c;逐步推广编程教育。本赛项是在贯彻…

Linux学习笔记————C 语言版 LED 灯实验

这里写目录标题 一、实验程序编写二、 汇编部分实验程序编写三、C 语言部分实验程序编写四、编译下载验证 汇编 LED 灯实验中&#xff0c;我们讲解了如何使用汇编来编写 LED 灯驱动&#xff0c;实际工作中是很少用到汇编去写嵌入式驱动的&#xff0c;毕竟汇编太难&#xff0c;而…

用于HUD平视显示器的控制芯片:S2D13V40

一款利用汽车抬头显示技术用于HUD平视显示器的控制芯片:S2D13V40。HUD的全称是Head Up Display&#xff0c;即平视显示器&#xff0c;以前应用于军用飞机上&#xff0c;旨在降低飞行员需要低头查看仪表的频率。起初&#xff0c;HUD通过光学原理&#xff0c;将驾驶相关的信息投射…

1.Git是用来干嘛的

本文章学习于【GeekHour】一小时Git教程&#xff0c;来自bilibili Git就是一个文件管理系统&#xff0c;这样说吧&#xff0c;当多个人同时在操作一个文件的同时&#xff0c;很容易造成紊乱&#xff0c;git就是保证文件不紊乱产生的 包括集中式管理系统和分布式管理系统 听懂…

00 - Logic Circuit 简介 -- 与或非门

---- 整理自B站UP主 踌躇月光 的视频 1. Logic Circuit Logic Circuit 下载地址 界面如下&#xff0c;实际使用可下载体验 2. 与或非门

HTML常用的图片标签和超链接标签

目录 一.常用的图片标签和超链接标签&#xff1a; 1.超链接标签&#xff1a; 前言: 超链接的使用&#xff1a; target属性: 1)鼠标样式&#xff1a; 2)颜色及下划线: 总结: 2.图片标签&#xff1a; 前言: img的使用: 设置图片&#xff1a; 1.设置宽度和高度: 2.HTM…

排序算法-归并排序

Leetcode链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 归并&#xff1a;将原始数组划分为若干个子数组&#xff0c;然后将这些子数组分别排序&#xff0c;最后再将已排序的子数组合并成一个有序的数组。是一种分治思想 思路&#xff1a; 1.分 2.治 3.怎么治 …

力扣1047. 删除字符串中的所有相邻重复项

思路&#xff1a;消消乐的感觉&#xff0c;就先想到栈&#xff1b;用一个栈存放遍历过的元素&#xff0c;和遍历中的下一个元素相比&#xff0c;相同则出栈&#xff0c;不同则入栈&#xff0c;最终栈内剩余的就是不相同的元素。 class Solution {public String removeDuplicat…

C语言第三十九弹---预处理(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 预处理 1、预定义符号 2、#define定义常量 3、#define定义宏 4、带有副作用的宏参数 5、宏替换的规则 6、宏和函数的对比 总结 在C语言中&#xff0c;预处…

【C++】多态的原理

目录 一、虚函数表 1、虚函数表的定义 2、虚函数表特性 3、虚表的打印 二、多态的原理 三、多态的相关问题 1、指针偏移问题 2、输出的程序是什么&#xff1f; 3、输出的程序是什么&#xff1f; 【前言】 上一篇我们学习了多态的基础知识&#xff0c;这一篇我将带着大…

HarmonyOS 应用开发之通过数据管理服务实现数据共享静默访问

场景介绍 典型跨应用访问数据的用户场景下&#xff0c;数据提供方会存在多次被拉起的情况。 为了降低数据提供方拉起次数&#xff0c;提高访问速度&#xff0c;OpenHarmony提供了一种不拉起数据提供方直接访问数据库的方式&#xff0c;即静默数据访问。 静默数据访问通过数据…

Incus:新一代容器与虚拟机编排管理引擎

Incus是什么&#xff1f; Incus是一个用于编排管理应用型容器、系统型容器及虚拟机实例的管理工具。它是对 Canonical LXD 的继承与发展&#xff0c;引入了更多的存储驱动支持。 Incus项目的产品地址&#xff1a;Linux Containers - Incus - Introduction 在 LXC-Incus 项目…

KnowLog:基于知识增强的日志预训练语言模型|顶会ICSE 2024论文

徐波 东华大学副教授 东华大学计算机学院信息技术系副系主任&#xff0c;复旦大学知识工场实验室副主任&#xff0c;智能运维方向负责人。入选“上海市青年科技英才扬帆计划”。研究成果发表在IJCAI、ICDE、ICSE、ISSRE、ICWS、CIKM、COLING等国际会议上&#xff0c;曾获中国数…

【turtle海龟先生】神奇的“圆”,画,太极圈,铜钱古币

turtle画圆三步法 步骤: 1、导入turtle库 2、确定半径&#xff0c;画圆(circle ) 3、结束(done ) turtle 库中提供一个直接画圆的函数 turtle.circle&#xff08;半径&#xff09;#半径单位为像素 例&#xff1a; turtle.circle ( 100 ) 表示绘制一个半径为100像素长度的圆形 …

基于ROS的地图发布和加载(GAZEBO仿真)

文章目录 环境配置启动仿真运动控制地图保存地图加载Q&A环境配置 cd ~/catkin_ws/src git clone https://github.com/wh200720041/warehouse_simulation_toolkit.git cd .. catkin_make source ~/catkin_ws/devel/setup.bash启动仿真 roslaunch warehou

【软件工程】详细设计(二)

这里是详细设计文档的第二部分。前一部分点这里 4. 学生端模块详细设计 学生端模块主要由几个组件构成&#xff1a;学生登录界面&#xff0c;成绩查询界面等界面。因为学生端的功能相对来说比较单一&#xff0c;因此这里只给出两个最重要的功能。 图4.1 学生端模块流程图 4.…

软考高级架构师:性能评价方法概念和例题

一、AI 讲解 性能评价是衡量计算机系统或其组件在指定条件下执行预期任务的有效性的一种方式。性能评价的方法主要可以分为几种&#xff0c;每种方法都有其特点和适用场景。 性能评价方法 方法描述时钟频率法通过计算机的时钟频率来评估性能&#xff0c;时钟频率越高&#x…