【附录】为什么说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容器通过这种精心设计的数据结构和算法,实现了高效的对象管理和依赖注入功能。

相关推荐
dylan_QAQ1 小时前
【附录】BeanFactoryPostProcessor的作用时机与核心实现?
后端·spring
it自1 小时前
SpringMVC在前后端分离架构中的执行流程详解
java·spring boot·后端·spring·架构
dylan_QAQ2 小时前
【附录】在spring中BeanDefinition 来源是由哪些?如何理解 BeanDefinition ,他在spring中起到了什么作用?
后端·spring
dylan_QAQ2 小时前
Spring 容器详解
后端·spring
dylan_QAQ2 小时前
【附录】举例说明Spring是如何进行 创建、配置和管理 对象的呢?
spring
斜月3 小时前
Spring 自动装配原理即IOC创建流程
spring boot·后端·spring
半部论语4 小时前
Spring **${}** vs **#{}** 语法全景图
java·数据库·spring boot·后端·spring
知行合一。。。4 小时前
Spring--04--2--AOP自定义注解,数据过滤处理
java·后端·spring
dylan_QAQ5 小时前
Spring 事件机制详解
spring