BeanFactory
- Spring之BeanFactory
-
- 什么是BeanFactory
- ApplicationContext相对BeanFactory实现的功能性扩展
-
- [1. MessageSource](#1. MessageSource)
- [2. ResourcePatternResolver](#2. ResourcePatternResolver)
- [3. ApplicationEventPublisher](#3. ApplicationEventPublisher)
- [4. EnvironmentCapable](#4. EnvironmentCapable)
- 通用ApplicationContext实践实现BeanFactory
- BeanFactory后处理器排序让谁优先执行
- 第一种实现通过xml等方式实现的bean注入原理
-
- [第二种基于磁盘路径下 xml 格式的配置文件来创建](#第二种基于磁盘路径下 xml 格式的配置文件来创建)
- 第三种较为经典的容器,基于java配置类来创建
- 第四种较为经典的容器,基于java配置类来创建,并且还可以用于web环境
Spring之BeanFactory
什么是BeanFactory
BeanFactory是SpringApplication类的父类接口
BeanFactory才是Spring的核心容器,主要的SpringApplication类都组合了他的功能。
通过Ctrl+alt+u可以看到
可以从图片中看到SpringApplication是继承了BeanFactory接口对BeanFactory进行了功能性的扩展。
比如SpringApplication获取一个bean的对象
run.getBean(BreadRollMallServer.class);
他实际上是通过组合了BeanFactory实现找个获取对象的功能,可以看出来SpringApplication是间接的调用了BeanFactory的功能
ApplicationContext相对BeanFactory实现的功能性扩展

1. MessageSource
MessageSource 是 Spring 框架里用于消息解析与国际化的核心接口。借助它,你能够依据不同的语言环境获取对应的文本消息,从而实现国际化支持。像错误消息、提示信息这类文本内容,就可以通过 MessageSource 进行管理。
2. ResourcePatternResolver
ResourcePatternResolver 接口可用来解析资源路径,并且支持使用通配符来匹配多个资源。它是 ResourceLoader 的扩展,能够依据给定的资源路径模式查找多个资源。在加载配置文件、静态资源等场景中会经常用到。
3. ApplicationEventPublisher
ApplicationEventPublisher 接口提供了发布应用事件的功能。在 Spring 应用里,事件机制是一种重要的设计模式,允许组件之间以松耦合的方式进行通信。通过 ApplicationEventPublisher,你可以发布自定义的应用事件,其他组件可以监听这些事件并做出响应。
应用场景:用户注册时候的发短信发邮件。
4. EnvironmentCapable
EnvironmentCapable 接口表明一个对象具备获取 Environment 对象的能力。Environment 对象封装了应用程序运行时的环境信息,包含系统属性、环境变量、配置文件属性等。借助 Environment,你可以方便地获取和管理这些属性。
通用ApplicationContext实践实现BeanFactory
public class TestBeanFactory {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// bean 的定义(class(类型), scope(单例or多例), 初始化方法, 销毁方法)
// BeanDefinitionBuilder..xxx.xxx.xxx.getBeanDefinition()
AbstractBeanDefinition beanDefinition =
BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
//(beanName,xxx)将bean注册到bean工厂中
beanFactory.registerBeanDefinition("config", beanDefinition);
// 【重点】给 BeanFactory 添加一些常用的后处理器(对BeanFactory的扩展)
//将后处理添加到bean工厂
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
// BeanFactory 后处理器主要功能,补充了一些 bean 定义
// beanFactory.getBeansOfType 根据类型获取多个bean
//BeanFactoryPostProcessor.class拿到bean工厂的所有后处理器,对bean工厂做出扩展就可以解析@bean注解等。
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
//拿到bean工厂的所有后处理器并且执行
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);//执行BeanFactory后置处理器
});
// 添加 BeanPostProcessor 也就是添加bean的后处理器
//bean后处理器 针对bean的生命周期各个阶段进行扩展,例如@Autowire @Resouse
beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);
for (String name : beanFactory.getBeanDefinitionNames()) {
System.out.println(name);
}
}
@Configuration
static class Config {
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean
public Bean2 bean2() {
return new Bean2();
}
}
static class Bean1 {
private static final Logger log = LoggerFactory.getLogger(Bean1.class);
@Autowired
private Bean2 bean2;
}
static class Bean2 {
private static final Logger log = LoggerFactory.getLogger(Bean2.class);
}
}
通过这个案例,你可以看到如何使用 DefaultListableBeanFactory 创建和管理 Bean,以及如何使用后置处理器在 Bean 的生命周期中执行自定义逻辑。
区别对比
- 作用时机
BeanFactoryPostProcessor:在 BeanFactory 完成 Bean 定义的加载之后,但在 Bean 实例化之前执行。也就是说,它处理的是 Bean 的定义信息,而不是 Bean 实例。
BeanPostProcessor:在 Bean 实例化之后,初始化前后执行。它作用于已经创建好的 Bean 实例。 - 作用对象
BeanFactoryPostProcessor:作用于 BeanFactory 本身,主要用于修改 BeanFactory 中 Bean 的定义信息,例如修改 Bean 的属性值、作用域等。
BeanPostProcessor:作用于具体的 Bean 实例,允许开发者在 Bean 初始化前后对其进行定制化处理。 - 功能侧重点
BeanFactoryPostProcessor:侧重于对 Bean 定义的全局修改和扩展,例如动态添加或修改 Bean 定义,调整 Bean 的配置等。
BeanPostProcessor:侧重于对 Bean 实例的个性化处理,例如对 Bean 进行增强、验证、日志记录等。
总结:
1.bean工厂不会主动调用beanFactory后处理器
2.bean不会主动添加后处理器
3.不会主动初始化单例
4.不会解析BeanFactory
BeanFactory后处理器排序让谁优先执行

第一种实现通过xml等方式实现的bean注入原理
通过xml注入bean容器
// ⬇️1.最为经典的容器,基于classpath 下 xml 格式的配置文件来创建
public void testClassPathXmlApplicationContext() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring_bean.xml");
for (String name : context.getBeanDefinitionNames()) {
System.out.println(name);
}
System.out.println(context.getBean(Bean2.class).getBean1());
}
第二种基于磁盘路径下 xml 格式的配置文件来创建
//基于磁盘路径下 xml 格式的配置文件来创建
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
System.out.println("读取之前");
for (String name : beanFactory.getBeanDefinitionNames()) {
System.out.println(name);
}
System.out.println("读取之后");
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);;
reader.loadBeanDefinitions(new FileSystemResource("src\\main\\resources\\spring_bean.xml"));
for (String name : beanFactory.getBeanDefinitionNames()) {
System.out.println(name);
}
第三种较为经典的容器,基于java配置类来创建
较为经典的容器,基于java配置类来创建,通过这个配置类创建会帮我们创建后处理器了来解析@Bean注解
// ⬇️3.较为经典的容器,基于java配置类来创建
public void testAnnotationConfigApplicationContext() {
// 会自动加上5个后处理器
// org.springframework.context.annotation.internalConfigurationAnnotationProcessor
// org.springframework.context.annotation.internalAutowiredAnnotationProcessor
// org.springframework.context.annotation.internalCommonAnnotationProcessor
// org.springframework.context.event.internalEventListenerProcessor
// org.springframework.context.event.internalEventListenerFactory
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
for (String name : context.getBeanDefinitionNames()) {
System.out.println(name);
}
System.out.println(context.getBean(Bean2.class).getBean1());
}
// 单元测试的过程中如果要解析一些Spring注解,比如@Configuration的时候不要把相关类定义到写单元测试类的内部类,会读取不到
@Configuration
class Config {
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean
public Bean2 bean2(Bean1 bean1) {
Bean2 bean2 = new Bean2();
bean2.setBean1(bean1);
return bean2;
}
}
class Bean1 {
}
class Bean2 {
private Bean1 bean1;
public Bean1 getBean1() {
return bean1;
}
public void setBean1(Bean1 bean1) {
this.bean1 = bean1;
}
}
第四种较为经典的容器,基于java配置类来创建,并且还可以用于web环境
// 模拟了 springboot web项目内嵌Tomcat的工作原理
public void testAnnotationConfigServletWebServerApplicationContext() throws IOException {
AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
// 防止程序终止
System.in.read();
}
@Configuration
class WebConfig {
@Bean
// 1. WebServer工厂
public ServletWebServerFactory servletWebServerFactory() {
return new TomcatServletWebServerFactory();
}
@Bean
// 2. web项目必备的DispatcherServlet
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
@Bean
// 3. 将DispatcherServlet注册到WebServer上
public DispatcherServletRegistrationBean dispatcherServletRegistrationBean(DispatcherServlet dispatcherServlet) {
return new DispatcherServletRegistrationBean(dispatcherServlet, "/");
}
@Bean("/hello")
public Controller controller1() {
return (request, response) -> {
response.getWriter().println("hello");
return null;
};
}
}