Spring Bean的初始化和实例化的区别
准确的说,标题中的初始化指的是Bean Definition的初始化,所以是完全不同的两个概念。普通的Java类如果想被SpringIOC容器托管,拥有强大的扩展功能和更强大的生命周期,用户(程序员)要做的只是写配置或者写注解,然后Spring会做这些事:首先,从xml或者注解扫描后的metadata中读取并加载Java类的原始数据到内存,通常是class二进制文件内容。其次,将...
·
实例化:是对象创建的过程。比如使用构造方法new对象,为对象在内存中分配空间。
初始化:是为对象中的属性赋值的过程。
在Spring中,AbstractAutowireCapableBeanFactory类的doCreateBean()方法描述了这个过程。
/**
* Actually create the specified bean. Pre-creation processing has already happened
* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
* <p>Differentiates between default bean instantiation, use of a
* factory method, and autowiring a constructor.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
*/
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//<1>实例化bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//<2>应用后置处理器修改bean definition
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//<3>饥饿加载单例bean,解决循环依赖问题
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//<4>如何解决循环依赖问题的呢,就是提前将实例化的bean放入缓存,以beanName->bean的引用的方式放入map,在createBean的上一步getBean的时候会从缓存中先拿bean。
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
//<5>初始化bean实例
Object exposedObject = bean;
try {
//<6>设置属性,如果属性是依赖注入的其他bean,走一遍getBean方法
populateBean(beanName, mbd, instanceWrapper);
//<7>初始化,调用aware方法、bean后置处理器的初始化前方法、初始化方法、bean后置处理器的初始化后方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
//<8>注册需要执行销毁回调的单例bean,比如在销毁方法中释放资源。
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
``<1>``实例化bean ``<2>``应用后置处理器修改bean definition ``<3>``饥饿加载单例bean,解决循环依赖问题 ``<4>``如何解决循环依赖问题的呢,就是提前将实例化的bean放入缓存,以beanName->bean的引用的方式放入map,在createBean的上一步getBean的时候会从缓存中先拿bean。 ``<5>``初始化bean实例 ``<6>``设置属性,如果属性是依赖注入的其他bean,走一遍getBean方法 ``<7>``初始化,调用aware方法、bean后置处理器的初始化前方法、初始化方法、bean后置处理器的初始化后方法 ``<8>``注册需要执行销毁回调的单例bean,比如在销毁方法中释放资源。
更多推荐
已为社区贡献1条内容
所有评论(0)