此文是 【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()方法的核心作用
- BeanFactory创建:创建Spring IoC容器的核心组件
- 配置加载:加载Bean定义和配置信息
- 资源管理:管理Bean的生命周期和依赖关系
- 扩展支持:为后续的Bean处理提供基础设施
方法的重要性
- 基础设施:为整个Spring容器提供Bean管理的基础设施
- 配置中心:集中管理所有的Bean定义和配置
- 扩展基础:为BeanFactoryPostProcessor等扩展点提供基础
- 性能关键:BeanFactory的创建和配置直接影响容器启动性能
最佳实践建议
- 合理配置BeanFactory:根据应用需求设置合适的参数
- 优化BeanDefinition加载:使用批量加载和缓存提高性能
- 监控启动性能:关注BeanFactory创建和配置的时间
- 异常处理:妥善处理Bean定义加载相关的异常
- 内存管理:合理设置缓存大小,避免内存泄漏
obtainFreshBeanFactory()
方法是Spring容器启动流程中的关键步骤,它创建了Spring IoC容器的核心基础设施。理解其工作原理对于深入理解Spring框架、优化应用启动性能以及解决相关问题都具有重要意义。