【附录】Spring容器启动流程详解 - obtainFreshBeanFactory()方法分析

此文是 【Spring 容器详解】-> 【【附录】Spring容器的启动过程】的支节点。

在Spring容器的启动过程中,AbstractApplicationContext.refresh()方法的第二个步骤是obtainFreshBeanFactory()。这个方法负责创建和配置Spring容器的核心组件------BeanFactory,它是整个Spring IoC容器的基础设施,负责Bean的定义、创建和管理。

1. obtainFreshBeanFactory()方法在refresh()流程中的位置

java 复制代码
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 1. 准备刷新
        prepareRefresh();
        
        // 2. 获取BeanFactory - 本文重点分析的方法
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        
        // 3. 准备BeanFactory
        prepareBeanFactory(beanFactory);
        
        try {
            // 4. 允许子类在标准初始化后修改BeanFactory
            postProcessBeanFactory(beanFactory);
            
            // 5. 调用BeanFactoryPostProcessor
            invokeBeanFactoryPostProcessors(beanFactory);
            
            // 6. 注册BeanPostProcessor
            registerBeanPostProcessors(beanFactory);
            
            // 7. 初始化消息源
            initMessageSource();
            
            // 8. 初始化事件广播器
            initApplicationEventMulticaster();
            
            // 9. 初始化特定上下文子类中的其他特殊bean
            onRefresh();
            
            // 10. 注册监听器
            registerListeners();
            
            // 11. 实例化所有非懒加载的单例Bean
            finishBeanFactoryInitialization(beanFactory);
            
            // 12. 完成刷新
            finishRefresh();
        } catch (BeansException ex) {
            // 清理资源
            destroyBeans();
            cancelRefresh(ex);
            throw ex;
        } finally {
            // 重置Spring通用的内省缓存
            resetCommonCaches();
        }
    }
}

2. obtainFreshBeanFactory()方法源码分析

2.1 方法签名和基本结构

java 复制代码
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
}

方法分析:

  • 返回类型ConfigurableListableBeanFactory - 可配置的可列出的Bean工厂
  • 主要逻辑:先刷新BeanFactory,然后返回刷新后的BeanFactory
  • 设计模式:使用了模板方法模式,具体的刷新逻辑由子类实现

2.2 refreshBeanFactory()方法详解

refreshBeanFactory()是一个抽象方法,由不同的ApplicationContext实现类提供具体实现。以AbstractRefreshableApplicationContext为例:

java 复制代码
protected final void refreshBeanFactory() throws BeansException {
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        // 创建新的BeanFactory
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        loadBeanDefinitions(beanFactory);
        this.beanFactory = beanFactory;
    } catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source", ex);
    }
}

步骤1: 检查现有BeanFactory

java 复制代码
if (hasBeanFactory()) {
    destroyBeans();
    closeBeanFactory();
}

作用:

  • 检查是否已经存在BeanFactory实例
  • 如果存在,先销毁所有已创建的Bean
  • 关闭现有的BeanFactory,释放资源
  • 确保每次刷新都是全新的BeanFactory

步骤2: 创建新的BeanFactory

java 复制代码
DefaultListableBeanFactory beanFactory = createBeanFactory();

createBeanFactory()方法:

java 复制代码
protected DefaultListableBeanFactory createBeanFactory() {
    return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}

DefaultListableBeanFactory的特点:

  • 实现了ConfigurableListableBeanFactory接口
  • 支持Bean定义的注册、修改和查询
  • 支持Bean的创建、依赖注入和生命周期管理
  • 支持作用域管理、循环依赖解决等高级功能

步骤3: 设置序列化ID

java 复制代码
beanFactory.setSerializationId(getId());

作用:

  • 为BeanFactory设置唯一的序列化标识符
  • 支持BeanFactory的序列化和反序列化
  • 在分布式环境中标识不同的BeanFactory实例

步骤4: 自定义BeanFactory

java 复制代码
customizeBeanFactory(beanFactory);

customizeBeanFactory()方法:

java 复制代码
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    if (this.allowBeanDefinitionOverriding != null) {
        beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
    }
    if (this.allowCircularReferences != null) {
        beanFactory.setAllowCircularReferences(this.allowCircularReferences);
    }
    if (this.allowEagerClassLoading != null) {
        beanFactory.setAllowEagerClassLoading(this.allowEagerClassLoading);
    }
}

主要配置项:

  • allowBeanDefinitionOverriding:是否允许Bean定义覆盖
  • allowCircularReferences:是否允许循环依赖
  • allowEagerClassLoading:是否允许提前加载类

步骤5: 加载Bean定义

java 复制代码
loadBeanDefinitions(beanFactory);

loadBeanDefinitions()方法: 这是一个抽象方法,由具体的ApplicationContext实现类实现:

java 复制代码
// AbstractXmlApplicationContext的实现
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException {
    // 创建XML Bean定义读取器
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    
    // 配置读取器
    beanDefinitionReader.setEnvironment(getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    
    // 加载Bean定义
    initBeanDefinitionReader(beanDefinitionReader);
    loadBeanDefinitions(beanDefinitionReader);
}

// AnnotationConfigApplicationContext的实现
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
    // 使用AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner
    AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(beanFactory);
    ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(beanFactory);
    
    // 注册配置类
    reader.register(componentClasses);
    // 扫描包
    scanner.scan(basePackages);
}

步骤6: 设置BeanFactory引用

java 复制代码
this.beanFactory = beanFactory;

作用:

  • 将新创建的BeanFactory实例保存到ApplicationContext中
  • 为后续的Bean操作提供BeanFactory引用

3. 不同ApplicationContext的BeanFactory创建差异

3.1 AbstractRefreshableApplicationContext

java 复制代码
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
    
    private volatile DefaultListableBeanFactory beanFactory;
    
    @Override
    protected final void refreshBeanFactory() throws BeansException {
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            customizeBeanFactory(beanFactory);
            loadBeanDefinitions(beanFactory);
            this.beanFactory = beanFactory;
        } catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source", ex);
        }
    }
    
    @Override
    public final ConfigurableListableBeanFactory getBeanFactory() {
        DefaultListableBeanFactory beanFactory = this.beanFactory;
        if (beanFactory == null) {
            throw new IllegalStateException("BeanFactory not initialized or already closed - " +
                    "call 'refresh' before accessing beans via the ApplicationContext");
        }
        return beanFactory;
    }
}

特点:

  • 每次refresh()都会创建新的BeanFactory
  • 支持热部署和配置重载
  • 适合需要动态更新配置的场景

3.2 GenericApplicationContext

java 复制代码
public class GenericApplicationContext extends AbstractApplicationContext implements BeanNameGenerator {
    
    private final DefaultListableBeanFactory beanFactory;
    
    public GenericApplicationContext() {
        this.beanFactory = new DefaultListableBeanFactory();
    }
    
    @Override
    protected final void refreshBeanFactory() throws IllegalStateException {
        if (!this.refreshed.compareAndSet(false, true)) {
            throw new IllegalStateException(
                    "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
        }
        this.beanFactory.setSerializationId(getId());
    }
    
    @Override
    public final ConfigurableListableBeanFactory getBeanFactory() {
        return this.beanFactory;
    }
}

特点:

  • BeanFactory在构造时就创建,不会重新创建
  • 不支持多次refresh()
  • 性能更好,适合单次初始化的场景

3.3 WebApplicationContext

java 复制代码
public abstract class AbstractRefreshableWebApplicationContext extends AbstractRefreshableApplicationContext 
    implements ConfigurableWebApplicationContext {
    
    private ServletContext servletContext;
    
    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException {
        // 加载Web相关的Bean定义
        XmlWebApplicationContext.loadBeanDefinitions(beanFactory, getConfigLocations());
    }
    
    @Override
    protected ConfigurableEnvironment createEnvironment() {
        return new StandardServletEnvironment();
    }
}

特点:

  • 继承自AbstractRefreshableApplicationContext
  • 支持Web环境相关的配置
  • 提供ServletContext访问能力

4. BeanDefinition加载过程详解

4.1 XML配置方式

java 复制代码
// XmlBeanDefinitionReader的工作流程
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
    
    public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
        return loadBeanDefinitions(new EncodedResource(resource));
    }
    
    public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
        // 1. 获取输入流
        InputStream inputStream = encodedResource.getResource().getInputStream();
        
        // 2. 创建SAX解析器
        InputSource inputSource = new InputSource(inputStream);
        
        // 3. 解析XML文档
        return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
    }
    
    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
        // 4. 解析XML并创建BeanDefinition
        Document doc = doLoadDocument(inputSource, resource);
        
        // 5. 注册BeanDefinition
        return registerBeanDefinitions(doc, resource);
    }
}

4.2 注解配置方式

java 复制代码
// AnnotatedBeanDefinitionReader的工作流程
public class AnnotatedBeanDefinitionReader {
    
    public void register(Class<?>... componentClasses) {
        for (Class<?> componentClass : componentClasses) {
            registerBean(componentClass);
        }
    }
    
    private void registerBean(Class<?> beanClass) {
        // 1. 创建AnnotatedGenericBeanDefinition
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
        
        // 2. 处理注解元数据
        AnnotationMetadata metadata = abd.getMetadata();
        
        // 3. 判断是否需要注册
        if (isComponent(metadata)) {
            // 4. 创建BeanDefinitionHolder
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
            
            // 5. 注册到BeanFactory
            BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
        }
    }
}

// ClassPathBeanDefinitionScanner的工作流程
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
    
    public int scan(String... basePackages) {
        int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
        
        doScan(basePackages);
        
        // 注册配置类后处理器
        if (this.includeAnnotationConfig) {
            AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
        }
        
        return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
    }
    
    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
        
        for (String basePackage : basePackages) {
            // 1. 扫描包下的类
            Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
            
            for (BeanDefinition candidate : candidates) {
                // 2. 处理作用域
                ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
                candidate.setScope(scopeMetadata.getScopeName());
                
                // 3. 生成Bean名称
                String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
                
                // 4. 注册BeanDefinition
                BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
                beanDefinitions.add(definitionHolder);
            }
        }
        
        return beanDefinitions;
    }
}

5. BeanFactory的核心功能配置

5.1 基础配置

java 复制代码
// 设置类加载器
beanFactory.setBeanClassLoader(getClassLoader());

// 设置表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));

// 设置属性编辑器注册器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

5.2 高级配置

java 复制代码
// 允许Bean定义覆盖
beanFactory.setAllowBeanDefinitionOverriding(true);

// 允许循环依赖
beanFactory.setAllowCircularReferences(true);

// 允许提前加载类
beanFactory.setAllowEagerClassLoading(true);

// 设置自动装配候选者解析器
beanFactory.setAutowireCandidateResolver(new SimpleAutowireCandidateResolver());

5.3 作用域配置

java 复制代码
// 注册自定义作用域
beanFactory.registerScope("thread", new SimpleThreadScope());
beanFactory.registerScope("session", new SessionScope());

// 设置默认作用域
beanFactory.setDefaultScope("singleton");

6. obtainFreshBeanFactory()方法的实际应用场景

6.1 热部署支持

java 复制代码
// 支持配置热更新的ApplicationContext
@Component
public class HotReloadableApplicationContext extends AnnotationConfigApplicationContext {
    
    private final File configFile;
    private long lastModified;
    
    public HotReloadableApplicationContext(File configFile) {
        this.configFile = configFile;
        this.lastModified = configFile.lastModified();
    }
    
    public boolean isConfigChanged() {
        return configFile.lastModified() > lastModified;
    }
    
    public void reload() {
        if (isConfigChanged()) {
            refresh();
            this.lastModified = configFile.lastModified();
        }
    }
}

6.2 多环境配置切换

java 复制代码
// 多环境配置管理器
@Component
public class EnvironmentConfigManager {
    
    private final ApplicationContext context;
    
    public EnvironmentConfigManager(ApplicationContext context) {
        this.context = context;
    }
    
    public void switchEnvironment(String profile) {
        if (context instanceof ConfigurableApplicationContext) {
            ConfigurableApplicationContext configContext = (ConfigurableApplicationContext) context;
            
            // 设置新的Profile
            configContext.getEnvironment().setActiveProfiles(profile);
            
            // 刷新容器
            configContext.refresh();
        }
    }
}

6.3 动态Bean注册

java 复制代码
// 动态Bean注册器
@Component
public class DynamicBeanRegistrar {
    
    private final DefaultListableBeanFactory beanFactory;
    
    public DynamicBeanRegistrar(ApplicationContext context) {
        this.beanFactory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory();
    }
    
    public void registerBean(String beanName, Class<?> beanClass) {
        // 创建BeanDefinition
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClass(beanClass);
        beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
        
        // 注册BeanDefinition
        beanFactory.registerBeanDefinition(beanName, beanDefinition);
    }
    
    public void removeBean(String beanName) {
        // 移除BeanDefinition
        beanFactory.removeBeanDefinition(beanName);
    }
}

7. 性能优化和最佳实践

7.1 BeanFactory创建优化

java 复制代码
// 优化BeanFactory创建
@Configuration
public class BeanFactoryOptimizationConfig {
    
    @Bean
    public DefaultListableBeanFactory optimizedBeanFactory() {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        
        // 设置合适的初始容量
        beanFactory.setAllowBeanDefinitionOverriding(false);
        beanFactory.setAllowCircularReferences(false);
        beanFactory.setAllowEagerClassLoading(false);
        
        // 预分配BeanDefinition存储空间
        beanFactory.setBeanDefinitionCount(1000);
        
        return beanFactory;
    }
}

7.2 BeanDefinition加载优化

java 复制代码
// 优化BeanDefinition加载
@Component
public class BeanDefinitionLoadingOptimizer {
    
    public void optimizeLoading(DefaultListableBeanFactory beanFactory) {
        // 批量加载BeanDefinition
        List<BeanDefinition> batchDefinitions = new ArrayList<>();
        
        // 使用批量注册提高性能
        for (BeanDefinition definition : batchDefinitions) {
            beanFactory.registerBeanDefinition(definition.getBeanClassName(), definition);
        }
    }
}

7.3 内存管理优化

java 复制代码
// 内存管理优化
@Configuration
public class MemoryOptimizationConfig {
    
    @Bean
    public BeanFactoryPostProcessor memoryOptimizer() {
        return beanFactory -> {
            if (beanFactory instanceof DefaultListableBeanFactory) {
                DefaultListableBeanFactory defaultFactory = (DefaultListableBeanFactory) beanFactory;
                
                // 清理未使用的BeanDefinition
                defaultFactory.clearMetadataCache();
                
                // 设置合理的缓存大小
                defaultFactory.setCacheBeanMetadata(true);
            }
        };
    }
}

8. 异常处理和调试

8.1 常见异常类型

8.1.1 BeanDefinitionStoreException

java 复制代码
// Bean定义存储异常
try {
    context.refresh();
} catch (BeanDefinitionStoreException e) {
    System.err.println("Bean定义存储失败: " + e.getMessage());
    System.err.println("资源位置: " + e.getResourceDescription());
    // 处理异常
}

8.1.2 ApplicationContextException

java 复制代码
// 应用上下文异常
try {
    context.refresh();
} catch (ApplicationContextException e) {
    System.err.println("应用上下文异常: " + e.getMessage());
    System.err.println("原因: " + e.getCause().getMessage());
    // 处理异常
}

8.2 调试技巧

java 复制代码
// BeanFactory调试工具
@Component
public class BeanFactoryDebugger {
    
    public void debugBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 打印所有Bean名称
        String[] beanNames = beanFactory.getBeanDefinitionNames();
        System.out.println("已注册的Bean数量: " + beanNames.length);
        
        for (String beanName : beanNames) {
            BeanDefinition definition = beanFactory.getBeanDefinition(beanName);
            System.out.println("Bean: " + beanName + " -> " + definition.getBeanClassName());
        }
        
        // 检查BeanFactory配置
        System.out.println("允许Bean定义覆盖: " + beanFactory.isAllowBeanDefinitionOverriding());
        System.out.println("允许循环依赖: " + beanFactory.isAllowCircularReferences());
    }
}

总结

obtainFreshBeanFactory()方法的核心作用

  1. BeanFactory创建:创建Spring IoC容器的核心组件
  2. 配置加载:加载Bean定义和配置信息
  3. 资源管理:管理Bean的生命周期和依赖关系
  4. 扩展支持:为后续的Bean处理提供基础设施

方法的重要性

  • 基础设施:为整个Spring容器提供Bean管理的基础设施
  • 配置中心:集中管理所有的Bean定义和配置
  • 扩展基础:为BeanFactoryPostProcessor等扩展点提供基础
  • 性能关键:BeanFactory的创建和配置直接影响容器启动性能

最佳实践建议

  1. 合理配置BeanFactory:根据应用需求设置合适的参数
  2. 优化BeanDefinition加载:使用批量加载和缓存提高性能
  3. 监控启动性能:关注BeanFactory创建和配置的时间
  4. 异常处理:妥善处理Bean定义加载相关的异常
  5. 内存管理:合理设置缓存大小,避免内存泄漏

obtainFreshBeanFactory()方法是Spring容器启动流程中的关键步骤,它创建了Spring IoC容器的核心基础设施。理解其工作原理对于深入理解Spring框架、优化应用启动性能以及解决相关问题都具有重要意义。

相关推荐
xuejianxinokok12 分钟前
解惑rust中的 Send/Sync(译)
后端·rust
Siler22 分钟前
Oracle利用数据泵进行数据迁移
后端
用户67570498850232 分钟前
3分钟,手摸手教你用OpenResty搭建高性能隧道代理(附完整配置!)
后端
coding随想1 小时前
网络世界的“快递站”:深入浅出OSI七层模型
后端·网络协议
skeletron20111 小时前
🚀AI评测这么玩(2)——使用开源评测引擎eval-engine实现问答相似度评估
前端·后端
shark_chili1 小时前
颠覆认知!这才是synchronized最硬核的打开方式
后端
就是帅我不改1 小时前
99%的Java程序员都写错了!高并发下你的Service层正在拖垮整个系统!
后端·架构
Apifox1 小时前
API 文档中有多种参数结构怎么办?Apifox 里用 oneOf/anyOf/allOf 这样写
前端·后端·测试
似水流年流不尽思念1 小时前
如何实现一个线程安全的单例模式?
后端·面试
楽码1 小时前
了解HMAC及实现步骤
后端·算法·微服务