【附录】为什么说BeanFactory和ApplicationContext是Spring容器?

【附录】为什么说BeanFactory和ApplicationContext是容器?

此文是【Spring 容器详解】的支节点。

容器的概念

容器 不仅仅是一个存储数据的结构,而是一个管理对象的系统。Spring的容器概念体现在:

  1. 管理功能 - 负责对象的创建、配置、生命周期管理
  2. 存储功能 - 存储对象及其元数据
  3. 查找功能 - 提供获取对象的方法
  4. 控制功能 - 控制对象的创建时机和方式

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是容器?

  1. 管理功能 - 提供Bean的创建、配置、生命周期管理
  2. 存储功能 - 通过内部的数据结构存储Bean
  3. 查找功能 - 提供获取Bean的方法
  4. 控制功能 - 控制Bean的创建时机和方式

真正存储Bean的类:

  1. DefaultListableBeanFactory - 核心存储容器

    • beanDefinitionMap - 存储BeanDefinition
    • singletonObjects - 存储单例Bean实例
    • earlySingletonObjects - 存储早期引用
    • singletonFactories - 存储Bean工厂
  2. 三级缓存机制 - 解决循环依赖

    • 一级缓存:完全初始化的Bean
    • 二级缓存:早期暴露的Bean
    • 三级缓存:Bean工厂
  3. BeanDefinition - 存储Bean的元数据

    • 类名、作用域、依赖关系等

Spring容器通过这种精心设计的数据结构和算法,实现了高效的对象管理和依赖注入功能。

相关推荐
憧憬成为java架构高手的小白9 小时前
黑马八股--spring框架学习
java·学习·spring
Nuanyt12 小时前
SSM 学习记录 第二部分 Spring整合Mybatis&Junit AOP核心概念 Spring事务管理 SpringMVC 请求与响应 Rest风格
java·spring·junit·mybatis·restful
米码收割机13 小时前
【SSM】Spring MVC_MyBatis SSM商城系统(源码+论文)【独一无二】
spring·mvc·mybatis
用户31268748772013 小时前
@Autowired 注入的是代理对象?Spring AOP 代理选择原理一次讲透
java·spring
小罗水14 小时前
第3章 从单体项目到 Spring Cloud 微服务
spring·spring cloud·微服务
Bug收容所15 小时前
12305项目学习day5
java·spring boot·redis·mysql·spring·rocketmq
lichuangcsdn15 小时前
【Spring AI 学习(三)】实现简单的对话
java·人工智能·学习·spring·spring ai
长不胖的路人甲15 小时前
Spring Bean 完整生命周期
java·spring·rpc
辰海Coding15 小时前
MiniSpring框架学习笔记-拦截器 :如何在方法前后进行拦截?
java·笔记·学习·spring·minispring
qq_185198691 天前
(Spring Bean + delegateExpression)实现http服务 的完整可运行项目
spring