概述
Spring Bean的加载过程是Spring框架的核心机制之一,它负责管理Bean的整个生命周期,从定义、实例化、依赖注入到销毁。理解这个过程对于深入掌握Spring框架至关重要。
核心概念
- Bean: Spring容器管理的对象实例
- BeanDefinition: Bean的元数据定义
- BeanFactory: Bean工厂,负责Bean的创建和管理
- ApplicationContext: 应用上下文,BeanFactory的高级实现
- IoC容器: 控制反转容器,管理对象的创建和依赖关系
Spring容器启动流程
1. 容器初始化
Spring容器的启动是通过ApplicationContext的实现类来完成的,主要有以下几种:
ClassPathXmlApplicationContext: 从类路径加载XML配置FileSystemXmlApplicationContext: 从文件系统加载XML配置AnnotationConfigApplicationContext: 基于注解的配置WebApplicationContext: Web应用上下文
2. refresh()方法详解
AbstractApplicationContext.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. 初始化MessageSource
initMessageSource();
// 8. 初始化事件广播器
initApplicationEventMulticaster();
// 9. 刷新特定上下文
onRefresh();
// 10. 注册监听器
registerListeners();
// 11. 实例化所有非懒加载的单例Bean
finishBeanFactoryInitialization(beanFactory);
// 12. 完成刷新
finishRefresh();
}
catch (BeansException ex) {
// 销毁已创建的Bean
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
Bean定义的解析
1. BeanDefinition接口
BeanDefinition是Spring中描述Bean元数据的核心接口:
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
// Bean的作用域常量
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
// 获取Bean的类名
String getBeanClassName();
// 获取Bean的作用域
String getScope();
// 是否为懒加载
boolean isLazyInit();
// 获取依赖的Bean名称
String[] getDependsOn();
// 是否为自动装配候选者
boolean isAutowireCandidate();
// 是否为主要候选者
boolean isPrimary();
}
2. Bean定义加载过程
根据Spring官方文档,Bean定义的加载主要通过以下核心方法实现:
2.1 AbstractRefreshableApplicationContext.loadBeanDefinitions()
// 抽象方法,由子类实现具体的Bean定义加载逻辑
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
throws BeansException, IOException
2.2 XmlBeanDefinitionReader加载过程
// 从Resource加载Bean定义
int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException
// 从多个Resource加载Bean定义
int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException
// 从指定位置加载Bean定义
int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException
2.3 实际加载实现
// XmlBeanDefinitionReader的核心加载方法
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException
3. XML配置解析
<bean id="userService" class="com.example.UserService">
<property name="userDao" ref="userDao"/>
</bean>
解析过程:
XmlBeanDefinitionReader读取XML文件- 解析
<bean>标签创建BeanDefinition - 注册到
BeanDefinitionRegistry
2. 注解配置解析
@Component
public class UserService {
@Autowired
private UserDao userDao;
}
解析过程:
ClassPathBeanDefinitionScanner扫描指定包- 识别
@Component等注解 - 创建
AnnotatedBeanDefinition - 处理
@Autowired等依赖注入注解
3. Java配置解析
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService();
}
}
解析过程:
ConfigurationClassPostProcessor处理@Configuration类- 解析
@Bean方法 - 创建
ConfigurationClassBeanDefinition
Bean实例化过程
1. getBean()方法调用链
// AbstractBeanFactory.getBean()
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
// doGetBean()核心逻辑
protected <T> T doGetBean(String name, Class<T> requiredType,
Object[] args, boolean typeCheckOnly) {
// 1. 转换Bean名称
String beanName = transformedBeanName(name);
// 2. 尝试从缓存获取
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 3. 检查循环依赖
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 4. 检查父工厂
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
return parentBeanFactory.getBean(originalBeanName(name), requiredType);
}
// 5. 标记Bean正在创建
markBeanAsCreated(beanName);
// 6. 获取BeanDefinition
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 7. 处理依赖的Bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
getBean(dep);
}
}
// 8. 创建Bean实例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
return createBean(beanName, mbd, args);
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
Object prototypeInstance = createBean(beanName, mbd, args);
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 其他作用域处理...
}
return (T) bean;
}
2. createBean()方法详解
// AbstractAutowireCapableBeanFactory.createBean()
protected Object createBean(String beanName, RootBeanDefinition mbd,
Object[] args) throws BeanCreationException {
// 1. 解析Bean类型
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
// 2. 准备方法覆盖
mbd.prepareMethodOverrides();
// 3. 给BeanPostProcessor机会返回代理对象
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null) {
return bean;
}
// 4. 实际创建Bean
Object beanInstance = doCreateBean(beanName, mbd, args);
return beanInstance;
}
3. doCreateBean()核心实现
protected Object doCreateBean(String beanName, RootBeanDefinition mbd,
Object[] args) throws BeanCreationException {
// 1. 创建Bean实例
BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
Object bean = instanceWrapper.getWrappedInstance();
// 2. 处理循环依赖 - 提前暴露Bean
boolean earlySingletonExposure = (mbd.isSingleton() &&
this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 3. 填充Bean属性(依赖注入)
populateBean(beanName, mbd, instanceWrapper);
// 4. 初始化Bean
Object exposedObject = initializeBean(beanName, bean, mbd);
// 5. 处理循环依赖检查
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
}
}
// 6. 注册销毁回调
registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
}
依赖注入机制
1. populateBean()方法
protected void populateBean(String beanName, RootBeanDefinition mbd,
BeanWrapper bw) {
// 1. 给InstantiationAwareBeanPostProcessor机会修改Bean状态
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp =
(InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
// 2. 获取属性值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 3. 自动装配
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME ||
resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 4. 处理@Autowired等注解
if (hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp =
(InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
pvs = pvsToUse;
}
}
}
// 5. 应用属性值
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
2. 注入方式对比
| 注入方式 | 实现机制 | 优缺点 |
|---|---|---|
| 构造器注入 | 通过构造函数参数 | 强制依赖,不可变,但可能造成循环依赖 |
| Setter注入 | 通过setter方法 | 可选依赖,灵活,但可能忘记注入 |
| 字段注入 | 直接设置字段值 | 简洁,但难以测试,违反封装性 |
Bean生命周期管理
1. initializeBean()方法
protected Object initializeBean(String beanName, Object bean,
RootBeanDefinition mbd) {
// 1. 调用Aware接口方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
// 2. 调用BeanPostProcessor的前置处理
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 3. 调用初始化方法
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Invocation of init method failed", ex);
}
// 4. 调用BeanPostProcessor的后置处理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
2. Aware接口调用
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
3. 初始化方法调用
protected void invokeInitMethods(String beanName, Object bean,
RootBeanDefinition mbd) throws Throwable {
// 1. 调用InitializingBean.afterPropertiesSet()
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null ||
!mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
((InitializingBean) bean).afterPropertiesSet();
}
// 2. 调用自定义初始化方法
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
4. Bean生命周期时序图
实例化 -> 属性注入 -> Aware接口 -> BeanPostProcessor前置 -> 初始化方法 -> BeanPostProcessor后置 -> 使用 -> 销毁
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
createBean populateBean invokeAware postProcessBefore initMethods postProcessAfter destroy
5. AutowireCapableBeanFactory中的后处理方法
根据Spring官方文档,AutowireCapableBeanFactory提供了应用BeanPostProcessor的核心方法:
// 对现有Bean实例应用初始化后的BeanPostProcessor
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
// 对现有Bean实例应用初始化前的BeanPostProcessor
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
6. 销毁前的后处理
对于实现了销毁回调的Bean,Spring还提供了销毁前的后处理:
// 在Bean销毁前应用后处理器
void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException
7. LifecycleProcessor接口
Spring提供了LifecycleProcessor接口来管理实现了Lifecycle接口的Bean:
/**
* 用于处理ApplicationContext中Lifecycle Bean的策略接口
* 管理生命周期Bean的启动和关闭顺序
*/
public interface LifecycleProcessor extends Lifecycle {
// 在上下文刷新时调用
void onRefresh();
// 在上下文关闭时调用
void onClose();
}
8. Bean销毁过程
根据Spring官方文档,Bean的销毁过程主要通过以下方法实现:
// AbstractApplicationContext中的销毁方法
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
// 上下文关闭时的核心逻辑
protected void doClose() {
// 销毁所有缓存的单例Bean
destroyBeans();
// 关闭BeanFactory
closeBeanFactory();
}
Bean销毁的详细流程:
- 销毁前后处理:调用
postProcessBeforeDestruction方法 - 执行销毁回调:调用
@PreDestroy注解的方法或destroy-method - 清理资源:从各种缓存中移除Bean引用
// DefaultSingletonBeanRegistry中的实现
public void destroySingletons() {
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
String[] disposableBeanNames;
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
}
高级特性
1. 循环依赖解决机制
Spring通过三级缓存解决单例Bean的循环依赖:
// 一级缓存:完成初始化的单例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);
解决流程:
- A创建过程中需要B,将A放入三级缓存
- 创建B过程中需要A,从三级缓存获取A的早期引用
- B完成创建,A注入B完成创建
2. 懒加载机制
@Component
@Lazy
public class LazyBean {
// 只有在第一次使用时才会创建
}
实现原理:
- 标记为懒加载的Bean不会在容器启动时创建
- 第一次调用
getBean()时才会触发创建 - 通过代理对象延迟实际Bean的创建
3. 条件化Bean创建
@Component
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
public class ConditionalBean {
// 只有在满足条件时才会创建
}
4. FactoryBean特殊处理
public class MyFactoryBean implements FactoryBean<MyObject> {
@Override
public MyObject getObject() throws Exception {
return new MyObject();
}
@Override
public Class<?> getObjectType() {
return MyObject.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
源码分析
1. 核心类关系图
BeanFactory (接口)
↓
ListableBeanFactory (接口)
↓
ConfigurableListableBeanFactory (接口)
↓
DefaultListableBeanFactory (实现类)
↑
ApplicationContext (接口)
↓
AbstractApplicationContext (抽象类)
↓
ClassPathXmlApplicationContext (实现类)
2. 关键接口和类
BeanDefinition
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
String getBeanClassName();
String getScope();
boolean isLazyInit();
String[] getDependsOn();
boolean isAutowireCandidate();
boolean isPrimary();
// ...
}
BeanPostProcessor
public interface BeanPostProcessor {
default Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
default Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
}
BeanFactoryPostProcessor
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException;
}
3. 扩展点总结
| 扩展点 | 作用时机 | 主要用途 |
|---|---|---|
| BeanFactoryPostProcessor | BeanFactory创建后,Bean实例化前 | 修改BeanDefinition |
| BeanPostProcessor | Bean初始化前后 | 修改Bean实例,创建代理 |
| InstantiationAwareBeanPostProcessor | Bean实例化前后 | 控制Bean实例化过程 |
| DestructionAwareBeanPostProcessor | Bean销毁前 | 自定义销毁逻辑 |
| Aware接口 | Bean初始化过程中 | 获取容器相关信息 |
常见面试题
1. 基础概念题
Q: Spring Bean的作用域有哪些?
A:
- singleton: 单例模式,整个容器中只有一个实例(默认)
- prototype: 原型模式,每次获取都创建新实例
- request: 每个HTTP请求创建一个实例(Web环境)
- session: 每个HTTP会话创建一个实例(Web环境)
- application: 每个ServletContext创建一个实例(Web环境)
- websocket: 每个WebSocket会话创建一个实例
Q: Spring如何解决循环依赖?
A: Spring通过三级缓存解决单例Bean的循环依赖:
- 一级缓存(singletonObjects): 存放完全初始化好的Bean
- 二级缓存(earlySingletonObjects): 存放原始的Bean对象(未填充属性)
- 三级缓存(singletonFactories): 存放Bean工厂对象
解决过程:
- A创建时发现依赖B,将A的工厂放入三级缓存
- 创建B时发现依赖A,从三级缓存获取A的早期引用
- B完成创建后,A继续完成创建
2. 源码实现题
Q: 描述Spring Bean的完整生命周期
A:
- 实例化: 通过反射创建Bean实例
- 属性注入: 设置Bean的属性值和依赖关系
- Aware接口回调: 调用BeanNameAware、BeanFactoryAware等
- BeanPostProcessor前置处理: 调用postProcessBeforeInitialization
- 初始化方法: 调用InitializingBean.afterPropertiesSet()和自定义init方法
- BeanPostProcessor后置处理: 调用postProcessAfterInitialization
- 使用阶段: Bean可以被应用程序使用
- 销毁: 调用DisposableBean.destroy()和自定义destroy方法
Q: @Autowired的实现原理是什么?
A:
- AutowiredAnnotationBeanPostProcessor负责处理@Autowired注解
- 在Bean实例化后,属性注入阶段被调用
- 通过反射找到标注@Autowired的字段和方法
- 根据类型从容器中查找匹配的Bean
- 如果找到多个,根据@Primary、@Qualifier或名称匹配
- 通过反射设置字段值或调用方法
3. 实践应用题
Q: 如何自定义BeanPostProcessor?
A:
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
// 初始化前处理
if (bean instanceof MyService) {
System.out.println("Before initialization: " + beanName);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
// 初始化后处理,可以返回代理对象
if (bean instanceof MyService) {
return Proxy.newProxyInstance(
bean.getClass().getClassLoader(),
bean.getClass().getInterfaces(),
(proxy, method, args) -> {
System.out.println("Method called: " + method.getName());
return method.invoke(bean, args);
}
);
}
return bean;
}
}
Q: 如何实现Bean的条件化创建?
A:
// 1. 使用@Conditional注解
@Component
@Conditional(DatabaseCondition.class)
public class DatabaseService {
// 只有在满足条件时才创建
}
public class DatabaseCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getEnvironment().getProperty("database.enabled", Boolean.class, false);
}
}
// 2. 使用Spring Boot的条件注解
@Component
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
public class FeatureService {
// 基于配置属性的条件创建
}
@Component
@ConditionalOnClass(DataSource.class)
public class DataSourceService {
// 基于类存在的条件创建
}
4. 性能优化题
Q: 如何优化Spring Bean的加载性能?
A:
- 使用懒加载: 对非必需的Bean使用@Lazy注解
- 减少Bean扫描范围: 精确指定@ComponentScan的包路径
- 使用@Profile: 根据环境加载不同的Bean配置
- 避免循环依赖: 重构代码消除不必要的循环依赖
- 使用@ConditionalOn*: 条件化创建Bean,避免不必要的实例化
- 合理使用单例和原型: 根据实际需求选择合适的作用域
Q: Spring Boot的自动配置原理是什么?
A:
- @EnableAutoConfiguration启用自动配置
- SpringFactoriesLoader加载META-INF/spring.factories文件
- AutoConfigurationImportSelector选择需要的自动配置类
- 条件注解控制配置类的生效条件
- 配置属性通过@ConfigurationProperties绑定外部配置
总结和最佳实践
1. 核心要点总结
- Spring Bean加载是一个复杂的生命周期管理过程,涉及实例化、依赖注入、初始化等多个阶段
- 三级缓存机制是解决循环依赖的关键,但只能解决单例Bean的循环依赖
- BeanPostProcessor提供了强大的扩展能力,是AOP、事务等功能的基础
- 不同的配置方式(XML、注解、Java配置)最终都会转换为BeanDefinition
- 容器启动的refresh()方法是整个加载过程的核心入口
2. 开发最佳实践
依赖注入建议
// 推荐:构造器注入,强制依赖,便于测试
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
// 避免:字段注入,难以测试
@Service
public class UserService {
@Autowired
private UserRepository userRepository; // 不推荐
}
生命周期管理
@Component
public class ResourceManager implements InitializingBean, DisposableBean {
private Resource resource;
@Override
public void afterPropertiesSet() throws Exception {
// 初始化资源
resource = createResource();
}
@Override
public void destroy() throws Exception {
// 清理资源
if (resource != null) {
resource.close();
}
}
}
条件化配置
@Configuration
public class DatabaseConfig {
@Bean
@ConditionalOnProperty(name = "database.type", havingValue = "mysql")
public DataSource mysqlDataSource() {
return new HikariDataSource();
}
@Bean
@ConditionalOnProperty(name = "database.type", havingValue = "h2")
public DataSource h2DataSource() {
return new EmbeddedDatabaseBuilder().build();
}
}
3. 性能优化建议
- 合理使用懒加载:对于启动时不需要的Bean使用@Lazy
- 精确扫描范围:避免扫描不必要的包
- 避免循环依赖:通过重构代码消除循环依赖
- 使用Profile:根据环境加载不同的配置
- 监控Bean创建时间:识别创建耗时的Bean进行优化
4. 调试技巧
// 1. 启用Debug日志
logging.level.org.springframework.beans=DEBUG
logging.level.org.springframework.context=DEBUG
// 2. 使用ApplicationContextAware获取容器信息
@Component
public class BeanInspector implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
// 打印所有Bean名称
String[] beanNames = applicationContext.getBeanDefinitionNames();
System.out.println("Total beans: " + beanNames.length);
Arrays.stream(beanNames).forEach(System.out::println);
}
}
// 3. 使用@EventListener监听容器事件
@Component
public class ApplicationEventListener {
@EventListener
public void handleContextRefreshed(ContextRefreshedEvent event) {
System.out.println("Application context refreshed");
}
@EventListener
public void handleContextClosed(ContextClosedEvent event) {
System.out.println("Application context closed");
}
}
Spring Bean的加载过程是Spring框架的核心机制,深入理解这个过程对于掌握Spring框架、进行性能优化和解决实际问题都具有重要意义。通过本文的详细分析,相信你已经对Spring Bean的加载过程有了全面的认识。
文章标签
冬眠
博主专注于技术、阅读与思考。在这里记录学习、思考与生活。
