此文是 【Spring 容器详解】-> 【【附录】Spring容器的启动过程】的支节点。
在Spring容器的启动过程中,AbstractApplicationContext.refresh()方法的第三个步骤是prepareBeanFactory()。这个方法负责为BeanFactory配置各种基础设施组件,包括类加载器、表达式解析器、属性编辑器、BeanPostProcessor等,为后续的Bean创建和管理提供必要的支持。
1. prepareBeanFactory()方法在refresh()流程中的位置
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. prepareBeanFactory()方法源码分析
2.1 方法签名和基本结构
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// 设置表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 设置属性编辑器注册器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加ApplicationContextAwareProcessor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 忽略依赖接口
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// 注册依赖
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 添加ApplicationListenerDetector
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 添加LoadTimeWeaverAwareProcessor
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
}
// 设置临时类加载器
if (!beanFactory.hasTempClassLoader()) {
beanFactory.setTempClassLoader(getTempClassLoader());
}
// 注册环境Bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
方法分析:
- 参数:
ConfigurableListableBeanFactory beanFactory- 可配置的可列出的Bean工厂 - 主要功能:为BeanFactory配置各种基础设施组件
- 设计目的:确保BeanFactory具备处理Bean创建、依赖注入、生命周期管理等能力
3. prepareBeanFactory()方法的详细功能分析
3.1 基础基础设施配置
3.1.1 设置类加载器
beanFactory.setBeanClassLoader(getClassLoader());
作用:
- 为BeanFactory设置类加载器,用于加载Bean类
- 支持从不同类路径加载Bean类
- 在Web环境中支持热部署和类重载
实际应用:
// 自定义类加载器示例
public class CustomClassLoader extends ClassLoader {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
// 自定义类加载逻辑
return super.loadClass(name);
}
}
// 在ApplicationContext中使用
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.setClassLoader(new CustomClassLoader());
3.1.2 设置表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
作用:
- 支持SpEL(Spring Expression Language)表达式解析
- 允许在Bean定义中使用表达式
- 支持动态属性值和条件化配置
实际应用:
// 在XML配置中使用SpEL表达式
<bean id="userService" class="com.example.UserService">
<property name="maxUsers" value="#{systemProperties['max.users'] ?: 100}"/>
<property name="timeout" value="#{T(java.lang.Math).random() * 1000}"/>
</bean>
// 在注解配置中使用SpEL表达式
@Component
public class UserService {
@Value("#{systemProperties['user.timeout'] ?: 5000}")
private long timeout;
@Value("#{userRepository.maxUsers}")
private int maxUsers;
}
3.1.3 设置属性编辑器注册器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
作用:
- 注册Spring内置的属性编辑器
- 支持将字符串转换为复杂对象类型
- 处理资源路径、环境变量等特殊属性
实际应用:
// 自动转换资源路径
@Component
public class FileService {
@Value("classpath:config.properties")
private Resource configFile;
@Value("file:/tmp/data.txt")
private Resource dataFile;
@Value("https://example.com/api")
private Resource remoteResource;
}
// 自动转换环境变量
@Component
public class DatabaseConfig {
@Value("${db.url}")
private String dbUrl;
@Value("${db.username}")
private String username;
@Value("${db.password}")
private String password;
}
3.2 BeanPostProcessor注册
3.2.1 ApplicationContextAwareProcessor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
作用:
- 处理各种Aware接口的回调
- 在Bean初始化过程中注入ApplicationContext相关的依赖
- 支持EnvironmentAware、ResourceLoaderAware等接口
支持的Aware接口:
// 环境感知
public interface EnvironmentAware {
void setEnvironment(Environment environment);
}
// 资源加载器感知
public interface ResourceLoaderAware {
void setResourceLoader(ResourceLoader resourceLoader);
}
// 应用事件发布器感知
public interface ApplicationEventPublisherAware {
void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher);
}
// 消息源感知
public interface MessageSourceAware {
void setMessageSource(MessageSource messageSource);
}
// 应用上下文感知
public interface ApplicationContextAware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
// 嵌入式值解析器感知
public interface EmbeddedValueResolverAware {
void setEmbeddedValueResolver(StringValueResolver resolver);
}
实际应用:
@Component
public class MyService implements ApplicationContextAware, EnvironmentAware {
private ApplicationContext applicationContext;
private Environment environment;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
public void doSomething() {
// 使用ApplicationContext
String[] beanNames = applicationContext.getBeanDefinitionNames();
// 使用Environment
String profile = environment.getActiveProfiles()[0];
}
}
3.2.2 ApplicationListenerDetector
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
作用:
- 检测实现了ApplicationListener接口的Bean
- 自动注册到ApplicationEventMulticaster
- 支持事件监听器的自动发现和注册
实际应用:
@Component
public class UserEventListener implements ApplicationListener<UserCreatedEvent> {
@Override
public void onApplicationEvent(UserCreatedEvent event) {
User user = event.getUser();
System.out.println("User created: " + user.getName());
}
}
// 事件发布
@Component
public class UserService {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void createUser(User user) {
// 创建用户逻辑
saveUser(user);
// 发布事件
eventPublisher.publishEvent(new UserCreatedEvent(this, user));
}
}
3.2.3 LoadTimeWeaverAwareProcessor
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
}
作用:
- 支持LoadTimeWeaver(加载时织入)
- 用于AOP的字节码增强
- 支持AspectJ的编译时和加载时织入
实际应用:
// 配置LoadTimeWeaver
@Configuration
@EnableLoadTimeWeaving
public class AopConfig {
@Bean
public LoadTimeWeaver loadTimeWeaver() {
return new ReflectiveLoadTimeWeaver();
}
}
// 使用AspectJ注解
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.*Service.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}
}
3.3 依赖接口忽略配置
// 忽略依赖接口
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
作用:
- 告诉Spring不要尝试自动装配这些接口
- 避免循环依赖问题
- 确保Aware接口通过BeanPostProcessor处理
原理:
- 当Spring进行依赖注入时,会跳过这些被忽略的接口
- 这些接口的依赖通过ApplicationContextAwareProcessor注入
- 避免了自动装配和手动注入的冲突
3.4 可解析依赖注册
// 注册依赖
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
作用:
- 注册可以直接注入的依赖类型
- 支持接口到具体实现的映射
- 简化依赖注入配置
实际应用:
@Component
public class MyService {
// 可以直接注入这些接口,Spring会自动解析为具体实现
@Autowired
private BeanFactory beanFactory;
@Autowired
private ResourceLoader resourceLoader;
@Autowired
private ApplicationEventPublisher eventPublisher;
@Autowired
private ApplicationContext applicationContext;
public void doSomething() {
// 使用BeanFactory
Object bean = beanFactory.getBean("someBean");
// 使用ResourceLoader
Resource resource = resourceLoader.getResource("classpath:config.properties");
// 使用ApplicationEventPublisher
eventPublisher.publishEvent(new CustomEvent(this));
// 使用ApplicationContext
String[] profiles = applicationContext.getEnvironment().getActiveProfiles();
}
}
3.5 环境Bean注册
// 注册环境Bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
作用:
- 注册环境相关的Bean到容器中
- 支持环境变量和系统属性的访问
- 为配置属性绑定提供支持
实际应用:
@Component
public class EnvironmentService {
@Autowired
private Environment environment;
@Autowired
private Map<String, Object> systemProperties;
@Autowired
private Map<String, String> systemEnvironment;
public void printEnvironmentInfo() {
// 访问环境变量
String[] activeProfiles = environment.getActiveProfiles();
String defaultProfile = environment.getDefaultProfiles()[0];
// 访问系统属性
String javaVersion = (String) systemProperties.get("java.version");
String userHome = (String) systemProperties.get("user.home");
// 访问系统环境变量
String path = systemEnvironment.get("PATH");
String home = systemEnvironment.get("HOME");
}
}
3.6 临时类加载器设置
// 设置临时类加载器
if (!beanFactory.hasTempClassLoader()) {
beanFactory.setTempClassLoader(getTempClassLoader());
}
作用:
- 设置临时类加载器用于特殊场景
- 支持动态类生成和字节码增强
- 在BeanFactory初始化完成后会被清除
4. prepareBeanFactory()方法的重要性
4.1 基础设施搭建
prepareBeanFactory()方法为Spring容器搭建了完整的基础设施:
- 类加载支持:确保Bean类能够正确加载
- 表达式解析:支持SpEL表达式和动态配置
- 属性转换:支持各种类型的属性注入
- Aware接口支持:自动注入ApplicationContext相关依赖
- 事件机制:支持事件监听器的自动发现
- AOP支持:支持加载时织入和字节码增强
4.2 扩展点准备
该方法注册了多个重要的BeanPostProcessor,为Spring的扩展机制提供了基础:
- ApplicationContextAwareProcessor:处理各种Aware接口
- ApplicationListenerDetector:自动发现事件监听器
- LoadTimeWeaverAwareProcessor:支持AOP增强
4.3 依赖注入支持
通过注册可解析依赖,简化了依赖注入的配置:
- 接口到实现映射:自动解析常用接口的具体实现
- 环境Bean注册:提供环境变量和系统属性访问
- 依赖忽略配置:避免循环依赖和注入冲突
5. 实际应用场景
5.1 自定义BeanPostProcessor
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof CustomAware) {
// 注入自定义依赖
((CustomAware) bean).setCustomService(getCustomService());
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// Bean初始化后的处理
return bean;
}
}
// 自定义Aware接口
public interface CustomAware {
void setCustomService(CustomService customService);
}
// 实现类
@Component
public class MyService implements CustomAware {
private CustomService customService;
@Override
public void setCustomService(CustomService customService) {
this.customService = customService;
}
}
5.2 环境配置管理
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig {
@Bean
public Environment environment() {
StandardEnvironment env = new StandardEnvironment();
// 添加自定义属性源
PropertiesPropertySource customSource = new PropertiesPropertySource("custom", getCustomProperties());
env.getPropertySources().addLast(customSource);
return env;
}
private Properties getCustomProperties() {
Properties props = new Properties();
props.setProperty("custom.key", "custom.value");
return props;
}
}
// 使用环境配置
@Component
public class ConfigService {
@Autowired
private Environment environment;
public String getCustomValue() {
return environment.getProperty("custom.key");
}
}
5.3 动态Bean注册
@Component
public class DynamicBeanRegistrar {
@Autowired
private DefaultListableBeanFactory beanFactory;
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);
}
}
6. 性能优化和最佳实践
6.1 BeanPostProcessor优化
// 优化BeanPostProcessor的执行顺序
@Component
public class OptimizedBeanPostProcessor implements BeanPostProcessor, PriorityOrdered {
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 只处理特定类型的Bean
if (bean instanceof OptimizableBean) {
return optimizeBean(bean);
}
return bean;
}
private Object optimizeBean(Object bean) {
// 优化逻辑
return bean;
}
}
6.2 类加载器优化
// 自定义类加载器优化
public class OptimizedClassLoader extends ClassLoader {
private final Map<String, Class<?>> classCache = new ConcurrentHashMap<>();
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
// 检查缓存
Class<?> cached = classCache.get(name);
if (cached != null) {
return cached;
}
// 加载类
Class<?> loaded = super.loadClass(name);
classCache.put(name, loaded);
return loaded;
}
}
6.3 表达式解析优化
// 自定义表达式解析器
public class CustomExpressionResolver implements BeanExpressionResolver {
private final Map<String, Object> expressionCache = new ConcurrentHashMap<>();
@Override
public Object evaluate(String value, BeanExpressionContext evalContext) throws BeansException {
// 检查缓存
Object cached = expressionCache.get(value);
if (cached != null) {
return cached;
}
// 解析表达式
Object result = doEvaluate(value, evalContext);
expressionCache.put(value, result);
return result;
}
private Object doEvaluate(String value, BeanExpressionContext evalContext) {
// 实际的表达式解析逻辑
return null;
}
}
7. 异常处理和调试
7.1 常见异常类型
7.1.1 BeanCreationException
// Bean创建异常
try {
context.refresh();
} catch (BeanCreationException e) {
System.err.println("Bean创建失败: " + e.getMessage());
System.err.println("Bean名称: " + e.getBeanName());
System.err.println("原因: " + e.getCause().getMessage());
// 处理异常
}
7.1.2 BeanDefinitionStoreException
// Bean定义存储异常
try {
context.refresh();
} catch (BeanDefinitionStoreException e) {
System.err.println("Bean定义存储失败: " + e.getMessage());
System.err.println("资源位置: " + e.getResourceDescription());
// 处理异常
}
7.2 调试技巧
// BeanFactory调试工具
@Component
public class BeanFactoryDebugger {
public void debugBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 检查BeanPostProcessor
BeanPostProcessor[] postProcessors = beanFactory.getBeanPostProcessors();
System.out.println("BeanPostProcessor数量: " + postProcessors.length);
for (BeanPostProcessor processor : postProcessors) {
System.out.println("Processor: " + processor.getClass().getSimpleName());
}
// 检查可解析依赖
System.out.println("可解析依赖类型: " + beanFactory.getResolvableDependencies().keySet());
// 检查环境Bean
String[] environmentBeans = {"environment", "systemProperties", "systemEnvironment"};
for (String beanName : environmentBeans) {
if (beanFactory.containsBean(beanName)) {
System.out.println("环境Bean存在: " + beanName);
}
}
}
}
总结
prepareBeanFactory()方法的核心作用
- 基础设施配置:设置类加载器、表达式解析器、属性编辑器等
- BeanPostProcessor注册:注册各种处理器支持Aware接口、事件监听等
- 依赖注入支持:配置可解析依赖和环境Bean
- 扩展机制准备:为Spring的扩展点提供基础支持
方法的重要性
- 基础设施:为BeanFactory提供完整的运行环境
- 扩展支持:支持各种Aware接口和事件机制
- 性能优化:通过合理的配置提高Bean创建和依赖注入的性能
- 功能增强:支持SpEL表达式、属性转换等高级功能
最佳实践建议
- 合理使用Aware接口:避免过度依赖ApplicationContext
- 优化BeanPostProcessor:按需实现,避免不必要的处理
- 缓存表达式结果:对于复杂的SpEL表达式考虑缓存
- 监控性能:关注BeanPostProcessor的执行时间
- 异常处理:妥善处理Bean创建和配置相关的异常
prepareBeanFactory()方法是Spring容器启动流程中的关键步骤,它为BeanFactory配置了完整的基础设施,确保Spring容器能够正常处理Bean的创建、依赖注入、生命周期管理等核心功能。