【附录】为什么说BeanFactory和ApplicationContext是容器?
此文是【Spring 容器详解】的支节点。
容器的概念
容器 不仅仅是一个存储数据的结构,而是一个管理对象的系统。Spring的容器概念体现在:
- 管理功能 - 负责对象的创建、配置、生命周期管理
- 存储功能 - 存储对象及其元数据
- 查找功能 - 提供获取对象的方法
- 控制功能 - 控制对象的创建时机和方式
BeanFactory和ApplicationContext的作用
java
// BeanFactory提供容器的基础功能
public interface BeanFactory {
// 获取Bean的核心方法
Object getBean(String name);
<T> T getBean(Class<T> requiredType);
// 容器管理功能
boolean containsBean(String name);
boolean isSingleton(String name);
Class<?> getType(String name);
}
// ApplicationContext扩展了更多企业级功能
public interface ApplicationContext extends BeanFactory {
// 事件发布
void publishEvent(ApplicationEvent event);
// 资源管理
Resource getResource(String location);
// 环境信息
Environment getEnvironment();
}
真正存储Bean的类
1. DefaultListableBeanFactory - 核心存储容器
DefaultListableBeanFactory
是Spring容器的核心实现类,它包含了真正存储Bean的数据结构:
java
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
// 存储BeanDefinition的Map - 存储Bean的定义信息
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
// 存储单例Bean的Map - 存储已创建的单例Bean实例
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 存储早期引用(用于解决循环依赖)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// 存储单例工厂(用于解决循环依赖)
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 存储Bean名称的List
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
// 存储已注册的Bean名称
private final Set<String> manualSingletonNames = new LinkedHashSet<>(16);
}
2. 三级缓存机制详解
Spring使用三级缓存来解决循环依赖问题:
java
public class DefaultSingletonBeanRegistry extends FactoryBeanRegistrySupport {
/** 一级缓存:存储完全初始化好的单例Bean */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** 二级缓存:存储早期暴露的Bean(未完全初始化) */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** 三级缓存:存储Bean的工厂对象 */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** 正在创建中的Bean名称 */
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
}
三级缓存的工作流程:
java
// 1. 创建Bean时,先放入三级缓存
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
}
}
}
// 2. 获取Bean时,按优先级查找
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 一级缓存:完全初始化好的Bean
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 二级缓存:早期暴露的Bean
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 三级缓存:Bean工厂
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
3. BeanDefinition的存储
java
public interface BeanDefinition {
// Bean的类名
void setBeanClassName(String beanClassName);
String getBeanClassName();
// Bean的作用域
void setScope(String scope);
String getScope();
// 是否懒加载
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
// 依赖的Bean
void setDependsOn(String... dependsOn);
String[] getDependsOn();
// 初始化方法
void setInitMethodName(String initMethodName);
String getInitMethodName();
// 销毁方法
void setDestroyMethodName(String destroyMethodName);
String getDestroyMethodName();
}
// 具体实现类
public class GenericBeanDefinition extends AbstractBeanDefinition {
private String beanClassName;
private String scope = BeanDefinition.SCOPE_DEFAULT;
private boolean lazyInit = false;
private String[] dependsOn;
private String initMethodName;
private String destroyMethodName;
// ... 其他属性
}
Spring容器的完整架构
1. 容器层次结构
java
// 基础容器接口
BeanFactory (基础功能)
↓
ApplicationContext (扩展企业级功能)
↓
AbstractApplicationContext (抽象实现)
↓
AnnotationConfigApplicationContext (注解配置实现)
↓
DefaultListableBeanFactory (真正的存储容器)
2. 核心组件关系
java
public class AnnotationConfigApplicationContext extends GenericApplicationContext {
// 真正的Bean存储容器
private final DefaultListableBeanFactory beanFactory;
// Bean定义扫描器
private final AnnotatedBeanDefinitionReader reader;
// 类路径扫描器
private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigApplicationContext() {
// 创建DefaultListableBeanFactory作为真正的存储容器
this.beanFactory = new DefaultListableBeanFactory();
// 创建Bean定义读取器
this.reader = new AnnotatedBeanDefinitionReader(this);
// 创建类路径扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
}
3. Bean的存储和获取流程
存储流程:
java
// 1. 扫描类,创建BeanDefinition
@Component
public class UserService {
// 扫描到@Component注解
}
// 2. 注册BeanDefinition到容器
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
// 存储到beanDefinitionMap
this.beanDefinitionMap.put(beanName, beanDefinition);
// 添加到beanDefinitionNames列表
this.beanDefinitionNames.add(beanName);
}
// 3. 创建Bean实例
public Object getBean(String name) {
// 从singletonObjects获取已创建的Bean
Object bean = this.singletonObjects.get(name);
if (bean != null) {
return bean;
}
// 如果不存在,则创建
return createBean(name);
}
// 4. 创建完成后存储到singletonObjects
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
获取流程:
java
// 1. 从ApplicationContext获取Bean
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = context.getBean(UserService.class);
// 2. 实际调用DefaultListableBeanFactory的方法
public <T> T getBean(Class<T> requiredType) {
// 根据类型查找Bean名称
String[] beanNames = getBeanNamesForType(requiredType);
if (beanNames.length == 1) {
// 获取Bean实例
return getBean(beanNames[0], requiredType);
}
// ... 处理多个Bean的情况
}
// 3. 从singletonObjects获取已创建的Bean
protected Object getSingleton(String beanName) {
return this.singletonObjects.get(beanName);
}
实际存储示例
1. BeanDefinition的存储
java
// 扫描到@Component注解的类
@Component
public class UserService {
@Autowired
private UserDao userDao;
}
// 创建BeanDefinition并存储
BeanDefinition userServiceDef = new GenericBeanDefinition();
userServiceDef.setBeanClassName("com.example.UserService");
userServiceDef.setScope("singleton");
userServiceDef.setLazyInit(false);
// 存储到beanDefinitionMap
beanDefinitionMap.put("userService", userServiceDef);
beanDefinitionNames.add("userService");
2. Bean实例的存储
java
// 创建Bean实例
UserService userService = new UserService();
// 注入依赖
userService.setUserDao(userDao);
// 调用初始化方法
userService.init();
// 存储到singletonObjects
singletonObjects.put("userService", userService);
3. 循环依赖的处理
java
// A依赖B,B依赖A的情况
@Component
public class ServiceA {
@Autowired
private ServiceB serviceB;
}
@Component
public class ServiceB {
@Autowired
private ServiceA serviceA;
}
// 解决过程:
// 1. 创建ServiceA实例(未完全初始化)
// 2. 将ServiceA放入三级缓存
singletonFactories.put("serviceA", () -> getEarlyBeanReference("serviceA", beanDefinition, serviceA));
// 3. 注入ServiceB时,发现ServiceB不存在,开始创建ServiceB
// 4. 创建ServiceB实例(未完全初始化)
// 5. 注入ServiceA时,从三级缓存获取早期引用
Object earlyReference = getSingleton("serviceA", true);
// 6. 将ServiceA从三级缓存移到二级缓存
earlySingletonObjects.put("serviceA", earlyReference);
singletonFactories.remove("serviceA");
// 7. 完成ServiceB的初始化,放入一级缓存
singletonObjects.put("serviceB", serviceB);
// 8. 完成ServiceA的初始化,放入一级缓存
singletonObjects.put("serviceA", serviceA);
总结
为什么说BeanFactory和ApplicationContext是容器?
- 管理功能 - 提供Bean的创建、配置、生命周期管理
- 存储功能 - 通过内部的数据结构存储Bean
- 查找功能 - 提供获取Bean的方法
- 控制功能 - 控制Bean的创建时机和方式
真正存储Bean的类:
-
DefaultListableBeanFactory - 核心存储容器
beanDefinitionMap
- 存储BeanDefinitionsingletonObjects
- 存储单例Bean实例earlySingletonObjects
- 存储早期引用singletonFactories
- 存储Bean工厂
-
三级缓存机制 - 解决循环依赖
- 一级缓存:完全初始化的Bean
- 二级缓存:早期暴露的Bean
- 三级缓存:Bean工厂
-
BeanDefinition - 存储Bean的元数据
- 类名、作用域、依赖关系等
Spring容器通过这种精心设计的数据结构和算法,实现了高效的对象管理和依赖注入功能。