BeanFactory作为Spring核心成员到底存在哪些变体---这些变体到底有多牛(漫威多元宇宙)

前言

〉 学习Spring,你一定遇到的纠结在于BeanFactory 和 FactoryBean 是啥玩意,Spring 起名页太不靠谱了吧。我只想说Spring的起名还是很见名知意的。虽然这两兄弟长得很像也很容易搞混淆,但是只要理解他们的作用你就再也不会纠结了。

  • 首先BeanFactory 就是一个bean工厂, 这是Spring的基石。接下来我们先看看BeanFactory. 光是了解学习它就需要很长的篇幅了,所以今天我们只谈BeanFactory. 至于FactoryBean 我们后续继续

容器接口

  • Spring 可以说是 Java 开发者的首选框架,没有之一。不知道这么说有没有要反驳 ~~~。
  • 我们启动一个 Spring 项目非常的简单。
java 复制代码
@SpringBootApplication
public class Application {
  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}
  • 不知道你有没有点进去 run 看看这个方法的结构。
java 复制代码
public static ConfigurableApplicationContext run(Class<?> primarySource,
			String... args) {
		return run(new Class<?>[] { primarySource }, args);
	}
  • 所以 ConfigurableApplicationContext 的地位不言而喻了吧。

BeanFactory

  • 通过看他的接口你可能会感觉 BeanFactory 好简单啊,基本上就一个 getBean 这个方法。但是它的内部还包括对 Bean 的生命周期管理,以及 Bean 的单例。
  • 这里我先强插一脚,在 Spring 中使用的是 DefaultListableBeanFactory 这个实现类作为 BeanFactory 的执行。我们也能够看到 DefaultListableBeanFactory 继承了很多类,这也说明它具备很多功能,不仅仅是 BeanFactory 中的 getBean。

    • SingletonBeanRegistry : 注册单例 Bean
    • HierarchicalBeanFactory : 父子容器
    • ListableBeanFactory : 列出容器内 Bean
    • BeanDefinitionRegistry : 注册Bean
  • 很多的功能来自于父类. 接下来我们来随便看看它的功能,比如查看容器内单例对象,为了演示方便,这里我们就不通过代码跟踪的方式获取了。直接暴力点

  • 因为我们的 ApplicationContext 本身就具备 BeanFactory 功能,所以只需要反射下就行。

java 复制代码
	ConfigurableApplicationContext configurableApplicationContext = SpringApplication.run(A0001Application.class);
	Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
	singletonObjects.setAccessible(true);
	Map<String, Object> o = (Map<String, Object>) singletonObjects.get(configurableApplicationContext.getBeanFactory());
	for (Map.Entry<String, Object> entry : o.entrySet()) {
		System.out.println("key:"+entry.getKey()+"
value:"+entry.getValue());
	}

ApplicationContext

  • 通过上面的 UML 类图,我们能够发现它继承了 BeanFactory,说明了它具有 BeanFactory 的能力,而 BeanFactory 是获取操作 Bean 的工具类。所以 ApplicationContext 地位更加的重要。
  • ApplicationContext 比 BeanFactory 多了点啥呢?
  • 我们只需要对比下 ConfigurableApplicationContext 和 DefaultListableBeanFactory 两个类的 UML 不难发现,ApplicationContext 大概多出了 MessageSource 、ResourcePatternResolver、ApplicationEventPublisher、EnvironmentCapble 这四个类的功能。
    • MessageSource : 国际化功能
    • ResourcePatternResolver : 通配符匹配路径资源, classpath://hello/**
    • ApplicationEventPublisher : 事件
    • EnvironmentCapble : 处理配置文件 yml 等属性。

MessageSource

  • 该功能是用来处理国际化的,处理国际化其实很简单,我们只需要在 resources 下准备好对应语言的提示文件,然后通过 ApplicationContext 获取对应参数的属性值即可。

  • 配置文件是 properties 所以在 idea 中我们需要设置下对应的文件编码,否则会出现非英文乱码的。

  • 接着我们在 resources 下分别准备 汉语、英语、日语 三国语言。
text 复制代码
hello=你好,新华
  • 每个文件中我们准备好对应的 key 即可,然后在代码中获取的时候指定语言和 key 即可。
java 复制代码
System.out.println(configurableApplicationContext.getMessage("hello", null, Locale.CHINA));
System.out.println(configurableApplicationContext.getMessage("hello", null, Locale.ENGLISH));
System.out.println(configurableApplicationContext.getMessage("hello", null, Locale.JAPANESE));

ResourcePatternResolver

  • 该类是支持通配符获取资源文件。在 ApplicationContext 中的体现就是 getResource
相关推荐
秋饼10 小时前
GPT-Live 全双工语音 API Java 服务端落地实战:事件协议、会话恢复与生产踩坑
java·ai·技术分享·后端开发
SL_staff10 小时前
为什么企业级自动化不能只靠AI编排?——逻辑引擎在确定性业务场景中的不可替代性
java·开源·产品
Pniubi11 小时前
MySQL靠什么实现事务的?事务隔离级别有哪些?
java·数据库·mysql
一条Go11 小时前
OnCall 时段路由:跨午夜、左闭右开与「Local 不是时区」
后端·架构·github
Moment11 小时前
不会后期的我,发现了一个开源胶片神器😍😍😍
前端·后端·开源
数据库小学妹11 小时前
pgbouncer 事务池:prepared statement、临时表与会话状态
数据库·后端·postgresql
松仔log12 小时前
Kotlin中级——callbackFlow
java·前端·kotlin
三小河12 小时前
SWC 凭什么比 Babel 快 ?项目优化迁移踩坑记录
前端·后端
鶴哥只手遮天12 小时前
《Redis 8.10.3 深度剖析》系列 ·第 17 章. 一个迟到十六年的类型
redis·后端·开源
知守观13 小时前
同一个团队两套分包:DDD 四层落地后,domain 层最大的类还是 5885 行
java·后端·领域驱动设计