对于类的初始化和实例化。实例化会不会一定是在初始化的基础上呢?之前验证以为实例化之前肯定会初始化,但是好像理解有问题,比如说springioc的bean的生命周期是4阶段,第一阶段是实例化,第三阶段是初始化,这样子不就是说明了初始化也可以在实例化后面了吗?也许之前理解有问题,看看有哪些uu浇浇
在容器关闭的时候,会进入Bean的销毁阶段,代码从AbstractApplicationContext的close()方法开始
不急着进入close()方法,先看一下第一节代码中最末尾的方法:
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
//如果Bean不是多例且需要在容器关闭时销毁
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
//给当前Bean绑定一个DisposableBeanAdapter
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
public void registerDisposableBean(String beanName, DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
}
在registerDisposableBeanIfNecessary中,会对每一个需要在容器关闭时进行销毁的单例Bean,绑定对应的DisposableBeanAdapter对象。最后把这些Bean及其DisposableBeanAdapter放入进名称为disposableBeans的map中,以供后续使用。
现在我们进入AbstractApplicationContext的close()方法
一路上兜兜转转,会进入到DefaultSingletonBeanRegistry的destroySingletons方法中
public void destroySingletons() {
String[] disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
//省略部分代码
}
先拿到所有待销毁Bean的名称,挨个调用destroySingleton方法,一直往下走,最终会进入到DefaultSingletonBeanRegistry的destroyBean中
其中核心的一句
// Actually destroy the bean now...
bean.destroy();
按照beanName从disposableBeans中获取到bean对应的DisposableBeanAdapter,调用其destroy方法
public void destroy() {
//调用被@PreDestroy注解修饰的方法
//具体可以跟进InitDestroyAnnotationBeanPostProcessor类
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
//如果实现了DisposableBean接口,则调用destroy方法
if (this.invokeDisposableBean) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((DisposableBean) this.bean).destroy();
return null;
}, this.acc);
} else {
((DisposableBean) this.bean).destroy();
}
}
//调用xml中自定义的destroy-method方法
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
} else if (this.destroyMethodName != null) {
Method methodToCall = determineDestroyMethod(this.destroyMethodName);
if (methodToCall != null) {
invokeCustomDestroyMethod(methodToCall);
}
}
}
到这里,Bean的销毁过程基本就结束了,我们使用一张图来概括下:
当一个类被加载时,会先进行类的实例化,然后才会进行初始化。Spring IOC中,实例化和初始化的顺序也是一样的,先实例化Bean对象,然后再进行初始化。初始化为基本类型的成员变量赋默认值,为引用类型的成员变量赋null值等。