在Spring框架中,Bean的初始化过程是非常重要的,它涉及到整个Spring应用程序的运行和配置。本文将深入分析Spring中Bean的初始化过程,从源码角度对其进行详细解析。
Bean的初始化过程
在Spring中,Bean的初始化过程主要包括以下几个步骤:
- 实例化Bean对象
- 设置Bean对象的属性值
- 调用Bean的初始化方法
- 返回Bean对象
下面我们将分析每个步骤的源码实现。
实例化Bean对象
首先,Spring会通过反射机制实例化Bean对象,这是通过BeanFactory的getBean方法实现的。具体实现代码如下:
protected Object doGetBean(final String name, final Class<?> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
final String beanName = transformedBeanName(name);
Object bean = null;
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
} else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
if (bean == null) {
// 创建Bean实例
bean = createBeanInstance(beanName, mbd, args);
}
return bean;
}
设置Bean对象的属性值
接下来,Spring会通过反射机制为Bean对象设置属性值。具体实现代码如下:
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
if (pvs.isEmpty()) {
return;
}
// 对Bean对象进行属性赋值
bw.setPropertyValues(pvs);
}
调用Bean的初始化方法
在属性值设置完成之后,Spring会调用Bean的初始化方法。初始化方法可以通过@Bean注解的initMethod属性指定,也可以通过实现InitializingBean接口来定义。具体实现代码如下:
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
} else {
((InitializingBean) bean).afterPropertiesSet();
}
}
}
返回Bean对象
最后一步是返回经过实例化、属性值设置和初始化方法调用后的Bean对象。Spring会将Bean对象保存在容器中,以供其他组件使用。具体实现代码如下:
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName,
@Nullable RootBeanDefinition mbd) {
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has factory method '" + name + "'");
}
return new FactoryBeanReference(beanName, (FactoryBean<?>) beanInstance);
}
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
Object object = doGetObjectFromFactoryBean((FactoryBean<?>) beanInstance, beanName);
if (object != beanInstance) {
validateScope(beanName, (FactoryBean<?>) beanInstance);
}
return object;
}
总结
通过以上分析,我们可以看到Spring中Bean的初始化过程是一个复杂的流程。Spring通过反射机制实例化Bean对象,设置属性值并调用初始化方法,最终返回Bean对象。这个过程非常关键,它决定了Spring应用程序的运行和配置。希望本文对您理解Spring中Bean的初始化过程有所帮助。如果您有任何问题或建议,请随时留言,我们将尽快回复。感谢阅读!
本文来自极简博客,作者:柔情似水,转载请注明原文链接:Spring源码解析之Bean的初始化过程详解