BeanFactory
是 Spring 框架的核心接口之一,负责管理 Spring 应用上下文中的所有 bean 对象。它是一个简单的 IOC(Inversion of Control)容器,是 ApplicationContext
的基础。以下是对 BeanFactory
接口的一些详细介绍:
主要功能
依赖注入:
BeanFactory
通过依赖注入机制管理和提供对象依赖关系。它根据配置元数据(通常是 XML 文件或注解)来实例化、配置和组装对象 (Home)。延迟初始化:
BeanFactory
采用延迟初始化策略,即只有在第一次访问 bean 时才会创建该 bean 实例。这与ApplicationContext
的预初始化策略不同,后者会在容器启动时创建所有单例 bean (Home)。Bean 配置和管理:
BeanFactory
提供了多种方法来获取和管理 bean 实例,例如getBean(String name)
和getBean(Class<T> requiredType)
等 (Home) (Home)。
主要方法
Object getBean(String name)
: 通过 bean 的名称来获取 bean 实例。Object getBean(String name, Object... args)
: 获取具有特定构造函数参数的 bean 实例。<T> T getBean(Class<T> requiredType)
: 通过 bean 的类型来获取 bean 实例。<T> T getBean(Class<T> requiredType, Object... args)
: 获取具有特定构造函数参数和类型的 bean 实例。boolean containsBean(String name)
: 检查容器中是否包含指定名称的 bean。boolean isSingleton(String name)
: 判断指定名称的 bean 是否为单例模式。boolean isPrototype(String name)
: 判断指定名称的 bean 是否为原型模式。boolean isTypeMatch(String name, Class<?> typeToMatch)
: 检查指定名称的 bean 是否匹配给定的类型。
与 ApplicationContext 的关系
BeanFactory
是 Spring IOC 容器的最基本接口,而ApplicationContext
是其高级子接口。ApplicationContext
在BeanFactory
的基础上添加了许多企业级特性,如国际化支持、事件传播、和不同的上下文实现(如WebApplicationContext
)等。ApplicationContext
通常在实际开发中更常用,因为它提供了更多的功能和更简便的使用方式 (Home) (Home)。
使用场景
BeanFactory
适合资源受限的环境,例如移动设备或嵌入式系统,因为它比 ApplicationContext
更轻量级。尽管如此,开发人员在大多数情况下更倾向于使用 ApplicationContext
,因为它提供了更全面的功能支持。
参考资料
- Spring Framework 官方文档
- Spring BeanFactory Interface
类图
BeanFactory 接口 和 实现类 DefaultListableBeanFactory
实现类 DefaultListableBeanFactory
BeanFactory
通过 registerBeanDefinition
方法注册一个 BeanDefinition
对象。BeanDefinition
描述了 bean 的详细信息,包括 scope(范围)、创建方式(构造函数或工厂方法)、初始化方法和销毁方法等。这些定义为 Spring 容器管理 bean 的创建和生命周期提供了蓝图。
Bean Definition
BeanDefinition
包含以下几个重要方面:
- Scope:bean 的作用范围,如 singleton 或 prototype。
- 创建方式:通过构造函数或工厂方法创建。
- 初始化和销毁方法:在 bean 的生命周期中调用的初始化和销毁回调方法。
- 属性和依赖:bean 所需的属性和依赖项注入信息。
注册 Bean Definition
我们常用的配置类、XML 配置、组件扫描等方式都是在生成
BeanDefinition
对象后,将其注册到BeanFactory
中。例如:
- 配置类:使用
@Configuration
和@Bean
注解。- XML 配置:通过
<bean>
元素定义。- 组件扫描:使用
@ComponentScan
注解扫描包路径下的组件。
BeanFactory 增强处理
BeanFactory
需要手动调用 BeanFactory 后处理器(BeanFactoryPostProcessor)来增强其功能。后处理器可以解析特定注解(如 @Bean
、@ComponentScan
),并补充 BeanDefinition
。典型的 BeanFactory 后处理器包括 ConfigurationClassPostProcessor
和 ComponentScanAnnotationParser
等。
添加 Bean 后处理器
BeanFactory
还需要手动添加 Bean 后处理器(BeanPostProcessor),以在 bean 创建过程中提供增强功能。例如,@Autowired
和 @Resource
注解的解析就是通过 Bean 后处理器完成的。常见的 Bean 后处理器包括 AutowiredAnnotationBeanPostProcessor
和 CommonAnnotationBeanPostProcessor
。
初始化单例 Bean
BeanFactory
需要手动调用 preInstantiateSingletons
方法来初始化单例 bean。这个方法会确保所有定义为单例的 bean 在容器启动时都被实例化和初始化。
解析 ${} 和 #{}
为了解析属性占位符(${}
)和 Spring 表达式语言(#{}
),BeanFactory
需要额外的设置。例如,可以通过添加 PropertySourcesPlaceholderConfigurer
来解析 ${}
,通过 StandardBeanExpressionResolver
来解析 #{}
。
示例代码:
package org.liuy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.LinkedList;
@Slf4j
public class BeanfactoryTest {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
AbstractBeanDefinition beanDefinition =
BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
beanFactory.registerBeanDefinition("config", beanDefinition);
// beanFactory 后处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor->{
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
});
// bean 后处理器
beanFactory.getBeansOfType(BeanPostProcessor.class).values()
.forEach(beanPostProcessor -> beanFactory.addBeanPostProcessor(beanPostProcessor));
// 预实例化
beanFactory.preInstantiateSingletons();
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
// log.info("beanFactory.getBean");
// System.out.println(beanFactory.getBean("config"));
System.out.println(beanFactory.getBean(Bean1.class).bean2);
// System.out.println(beanFactory.getBean(Bean2.class));
}
}
@Configuration
@Slf4j
class Config{
public Config() {
log.info("Config Construct");
}
@Bean
Bean1 bean1(){
return new Bean1();
}
@Bean
Bean2 bean2(){
return new Bean2();
}
}
@Slf4j
class Bean1{
public Bean1() {
log.info("Bean1 Construct");
}
@Autowired
public Bean2 bean2;
}
@Slf4j
class Bean2{
public Bean2() {
log.info("Bean2 Construct");
}
}