目录
五、初始化相关
执行initializeBean方法,进行初始化相关的操作。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 5.1 执行Aware
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 5.2 初始化前
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 5.3 初始化
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 5.4 初始化后 AOP
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
1、执行Aware
private void invokeAwareMethods(final String beanName, final 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);
}
}
}
Aware是感知的意思。我的理解: 让实例化后的对象能够感知自己在Spring容器里的存在的位置信息,创建信息等。例如BeanNameAware能够获取自己在spring容器当中的id(beanName),BeanClassLoaderAware能够获取加载自己的类加载器,BeanFactoryAware能够获取创建自己的Bean工厂。
public class UserService implements BeanNameAware {
private String beanName;
@Autowired
private User user;
@Override
public String toString() {
return "UserService{" +
"beanName='" + beanName + '\'' +
", user=" + user +
'}';
}
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println(this);
}
}
测试结果:
2、初始化前
拿出所有的后置处理器对bean进行处理,当有一个处理器返回null,将不再调用后面的处理器处理。
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// BPP1-->BPP2-->BPP3
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
@Component
public class TestBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println("userService:BeforeInitialization");
}
return bean;
}
}
public class UserService implements BeanNameAware {
private String beanName;
@Autowired
private User user;
@Override
public String toString() {
return "UserService{" +
"beanName='" + beanName + '\'' +
", user=" + user +
'}';
}
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println(this);
}
@PostConstruct
public void postConstruct() {
System.out.println(beanName + ":PostConstruct");
}
}
完成初始化前的操作有2种方式:
1.TestBeanPostProcessor 实现了 BeanPostProcessor ,重写postProcessBeforeInitialization方法。
2.使用@PostConstruct。由CommonAnnotationBeanPostProcessor处理器处理。
@PostConstruct是在实例化bean完成之后
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 实例化
// 原始对象
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 运行修改合并好了的BeanDefinition
// 这里会查找@Autowired的注入点(InjectedElement),并把这些注入点添加到mbd的属性externallyManagedConfigMembers中
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
//.....
}
在这里调用
InitDestroyAnnotationBeanPostProcessor的postProcessMergedBeanDefinition方法来解析的。
测试结果:
3、初始化
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.isTraceEnabled()) {
logger.trace("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();
}
}
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); // init-method=""
}
}
}
1.实现了InitializingBean接口的类执行其afterPropertiesSet()方法
2.从BeanDefinition中获取initMethod方法。
可以是xml文件中配置的:
<bean id="userService" class="com.spring.service.UserService" init-method="initMethod"/>
或者是@Bean注解配置:
@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
public UserService userService() {
return new UserService();
}
测试结果:
4、初始化后
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
同样是获取所有的bean的后置处理器去执行。
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
};
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
测试结果:
特别说明两点:
1.在实例化前如果获取到了bean那么将不执行spring正常创建bean的流程,而是直接调用初始化后的方法完成初始化后的操作。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
//....
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 1、实例化前 null
Object bean = resolveBeforeInstantiation(beanName, mbdToUse); // 对象
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// beforeInstantiationResolved为null或true
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 实例化前
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
2.通常情况下,如果一个Bean需要完成AOP【坑5】是在初始化后进行的。
六、注册DisposableBean
Spring在容器关闭时,会remove容器里所有的Bean。如果我们需要某些Bean在被Spring删除前执行一些逻辑,Spring也可以做到,那么就需要我们在Bean完成创建时将这个Bean注册为DisposableBean。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
//...
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
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));
}
}
}
Spring会在容器关闭时,执行所有DisposableBean的destory方法,完成销毁前的逻辑。
public interface DisposableBean {
void destroy() throws Exception;
}
1.Bean是否有注册为DisposableBean的资格:
不能是原型Bean(因为原型Bean不会放到Spring容器中),再通过requiresDestruction方法去判断一下是否需要销毁。
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
// 判断某个Bean是否拥有销毁方法
// 1. 实现了DisposableBean接口或AutoCloseable接口
// 2. BeanDefinition中定义了destroyMethodName
// 3. 类中是否存在@PreDestroy注解的方法
// 4. 由DestructionAwareBeanPostProcessor判断是否需要销毁
boolean flag = (
bean.getClass() != NullBean.class &&
(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) ||
(
hasDestructionAwareBeanPostProcessors() && DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors())
)
)
);
return flag;
}
1.1. 是否有destroyMethod。
判断是否有destroyMethod的方式有以下3种:
public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) {
if (bean instanceof DisposableBean || bean instanceof AutoCloseable) {
return true;
}
String destroyMethodName = beanDefinition.getDestroyMethodName();
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName)) {
return (ClassUtils.hasMethod(bean.getClass(), CLOSE_METHOD_NAME) ||
ClassUtils.hasMethod(bean.getClass(), SHUTDOWN_METHOD_NAME));
}
return StringUtils.hasLength(destroyMethodName);
}
1.实现了DisposableBean接口或AutoCloseable接口。
2. 有@PreDestroy标注的方法。
3. 在BeanDefinition中设置了销毁方法,设置销毁方法的方式有2种:
3.1. 在@Bean注解或 xml文件里的Bean标签直接指定方法名。
@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod666")
public UserService userService() {
return new UserService();
}
public class UserService{
public void destroyMethod666() {
System.out.println(beanName + ":destroy-method");
}
}
3.2 如果使用@Bean的方式定义一个Bean,即使不显示的指定destroyMethod,Spring也会有默认设置一个推断destroyMethod的标记(inferred)。当你有这个推断标记,Spring会去判断你的Bean当中是否定义了一个方法名为close的方法,或者shutdown方法。如果有,Spring会认为这是一个destroyMethod,并且将该Bean注册为DisposableBean。
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
//...
String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;
}
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
//...
/**
* Constant that indicates the container should attempt to infer the
* {@link #setDestroyMethodName destroy method name} for a bean as opposed to
* explicit specification of a method name. The value {@value} is specifically
* designed to include characters otherwise illegal in a method name, ensuring
* no possibility of collisions with legitimately named methods having the same
* name.
* <p>Currently, the method names detected during destroy method inference
* are "close" and "shutdown", if present on the specific bean class.
*/
public static final String INFER_METHOD = "(inferred)";
}
1.2. 是否有执行销毁方法的后置处理器。
由DestructionAwareBeanPostProcessor去标识一个Bean是否需要销毁,并且交给这个后置处理器去处理销毁前的逻辑。
public static boolean hasApplicableProcessors(Object bean, List<BeanPostProcessor> postProcessors) {
if (!CollectionUtils.isEmpty(postProcessors)) {
for (BeanPostProcessor processor : postProcessors) {
if (processor instanceof DestructionAwareBeanPostProcessor) {
DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
if (dabpp.requiresDestruction(bean)) {
return true;
}
}
}
}
return false;
}
@Component
public class TestBeanPostProcessor implements DestructionAwareBeanPostProcessor, BeanPostProcessor, InstantiationAwareBeanPostProcessor {
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println(beanName + ":即将销毁");
}
}
@Override
public boolean requiresDestruction(Object bean) {
if (bean instanceof UserService) {
return true;
}
return false;
}
//...
}
2.DisposableBeanAdapter
当一个bean有资格成为DisposableBean的时候,Spring不是将这个Bean直接放到需要销毁的容器当中,而是将其包装为DisposableBeanAdapter对象放入销毁容器中。
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
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));
}
}
}
单例Bean销毁容器是一个以beanName为key,DisposableBean为value的Map。
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** Disposable bean instances: bean name to disposable instance. */
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
public void registerDisposableBean(String beanName, DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
}
}
而其他作用域的Bean
public interface Scope {
void registerDestructionCallback(String name, Runnable callback);
}
比如request的销毁容器是一个以beanName为key,Runnable为value的Map。
public abstract class AbstractRequestAttributes implements RequestAttributes {
/** Map from attribute name String to destruction callback Runnable. */
protected final Map<String, Runnable> requestDestructionCallbacks = new LinkedHashMap<>(8);
protected final void registerRequestDestructionCallback(String name, Runnable callback) {
Assert.notNull(name, "Name must not be null");
Assert.notNull(callback, "Callback must not be null");
synchronized (this.requestDestructionCallbacks) {
this.requestDestructionCallbacks.put(name, callback);
}
}
}
DisposableBeanAdapter 就是一个DisposableBean。
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
/**
* Create a new DisposableBeanAdapter for the given bean.
* @param bean the bean instance (never {@code null})
* @param beanName the name of the bean
* @param beanDefinition the merged bean definition
* @param postProcessors the List of BeanPostProcessors
* (potentially DestructionAwareBeanPostProcessor), if any
*/
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = beanName;
this.invokeDisposableBean =
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.acc = acc;
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition); //
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
this.destroyMethodName = destroyMethodName;
Method destroyMethod = determineDestroyMethod(destroyMethodName);
if (destroyMethod == null) {
if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'");
}
}
else {
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
}
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
}
this.destroyMethod = destroyMethod;
}
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}
//...
}
2.1. 推断destoryMethod
在将Bean包装为DisposableBeanAdapter时,要去推断destoryMethod。
//挑选到底执行哪一个销毁方法,仅仅返回方法名称。
@Nullable
private String inferDestroyMethodIfNecessary(Object bean, RootBeanDefinition beanDefinition) {
//1.指定的destroyMethod就用
String destroyMethodName = beanDefinition.getDestroyMethodName();
//2.没有指定destroyMethodName,没有(inferred),而且没有实现AutoCloseable(close方法),返回null
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
(destroyMethodName == null && bean instanceof AutoCloseable)) {
// Only perform destroy method inference or Closeable detection
// in case of the bean not explicitly implementing DisposableBean
// 3.有(inferred),或者实现了AutoCloseable(close方法)
if (!(bean instanceof DisposableBean)) {
try {
//没有实现DisposableBean(destroy方法),并且有close方法就返回。
return bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex) {
try {
//没有close会报错,看有没有shutdown方法,有就返回
return bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex2) {
//没有shutdown方法报错,但异常被吞了,不做任何处理,返回null
// no candidate destroy method found
}
}
}
return null;
}
return (StringUtils.hasLength(destroyMethodName) ? destroyMethodName : null);
}
1.推断方法名:
1.1 如果指定了DestroyMethod 就返回指定的。
1.2 有推断标记或者实现了AutoCloseable接口,再看是否实现DisposableBean接口的;如果实现了就直接返回null,如果没有实现就去推断是否有公有close方法,有就返回,没有再去推断是否有公有的shutdown方法,有就返回。
2. 推断方法:
@Nullable
private Method findDestroyMethod(String name) {
return (this.nonPublicAccessAllowed ?
BeanUtils.findMethodWithMinimalParameters(this.bean.getClass(), name) :
BeanUtils.findMethodWithMinimalParameters(this.bean.getClass().getMethods(), name));
}
根据方法名推断方法,获取最少参数的方法对象method。如果method的参数大于1会报错,如果等于1且参数类型不为boolean类型也会报错。
3. 获取后置处理器
在判断是否有资格成为一个DisposableBean那里已经提到过,这里就不在赘述了。
3.完成注册
就是将完成包装的DisposableBeanAdapter,put到销毁容器中。
七、销毁
这里只关心单例Bean的销毁。Spring容器关闭时,会去销毁单例Bean。如果不去手动关闭容器,那么以上destroyMethod都不能执行。
public class UserService implements InitializingBean, BeanNameAware,DisposableBean{
private String beanName;
@Autowired
private User user;
@PreDestroy
public void preDestroy() {
System.out.println(beanName + ":@preDestroy");
}
public void destroy() throws Exception {
System.out.println(beanName + ":DisposableBean.destroy");
}
public void close() {
System.out.println(beanName + ":close");
}
public void shutdown() {
System.out.println(beanName + ":shutdown");
}
public void destroyMethod666(String name,int count) {
System.out.println(beanName + ":destroy-method"+",2个参数");
}
public void destroyMethod666(boolean name) {
System.out.println(beanName + ":destroy-method"+",1个boolean类型的参数");
}
@Override
public String toString() {
return "UserService{" +
"beanName='" + beanName + '\'' +
", user=" + user +
'}';
}
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println(this);
}
@PostConstruct
public void postConstruct() {
System.out.println(beanName + ":PostConstruct");
}
@Override
public void afterPropertiesSet() {
System.out.println(beanName + ":afterPropertiesSet");
}
public void initMethod() {
System.out.println(beanName + ":init-method");
}
public void beanDefinitionInitMethod() {
System.out.println(beanName + ": bd init-method");
}
}
这里发现并未执行销毁方法,applicationContext调用close方法可以关闭容器。
@Override
public void close() {
synchronized (this.startupShutdownMonitor) {
doClose();
// If we registered a JVM shutdown hook, we don't need it anymore now:
// We've already explicitly closed the context.
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
}
catch (IllegalStateException ex) {
// ignore - VM is already shutting down
}
}
}
}
doClose方法是真正执行关闭容器的逻辑。
protected void doClose() {
// Check whether an actual close attempt is necessary...
if (this.active.get() && this.closed.compareAndSet(false, true)) {
if (logger.isDebugEnabled()) {
logger.debug("Closing " + this);
}
LiveBeansView.unregisterApplicationContext(this);
try {
// Publish shutdown event.
publishEvent(new ContextClosedEvent(this));
}
catch (Throwable ex) {
logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
// Stop all Lifecycle beans, to avoid delays during individual destruction.
if (this.lifecycleProcessor != null) {
try {
this.lifecycleProcessor.onClose();
}
catch (Throwable ex) {
logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
}
}
// Destroy all cached singletons in the context's BeanFactory.
destroyBeans();
// Close the state of this context itself.
closeBeanFactory();
// Let subclasses do some final clean-up if they wish...
onClose();
// Reset local application listeners to pre-refresh state.
if (this.earlyApplicationListeners != null) {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Switch to inactive.
this.active.set(false);
}
}
1.判断是否执行销毁逻辑
destroyBeans()最终会调用destroyBean()里的destroy()去执行我们设置的那些destroyMethod方法。
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** Disposable bean instances: bean name to disposable instance. */ // DisposableBean
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
//...
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
// Trigger destruction of dependent beans first...
Set<String> dependencies;
synchronized (this.dependentBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
dependencies = this.dependentBeanMap.remove(beanName);
}
if (dependencies != null) {
if (logger.isTraceEnabled()) {
logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (String dependentBeanName : dependencies) {
destroySingleton(dependentBeanName);
}
}
// Actually destroy the bean now...
if (bean != null) {
try {
bean.destroy();
}
catch (Throwable ex) {
if (logger.isWarnEnabled()) {
logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
}
}
}
// Trigger destruction of contained beans...
Set<String> containedBeans;
synchronized (this.containedBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
containedBeans = this.containedBeanMap.remove(beanName);
}
if (containedBeans != null) {
for (String containedBeanName : containedBeans) {
destroySingleton(containedBeanName);
}
}
// Remove destroyed bean from other beans' dependencies.
synchronized (this.dependentBeanMap) {
for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Set<String>> entry = it.next();
Set<String> dependenciesToClean = entry.getValue();
dependenciesToClean.remove(beanName);
if (dependenciesToClean.isEmpty()) {
it.remove();
}
}
}
// Remove destroyed bean's prepared dependency information.
this.dependenciesForBeanMap.remove(beanName);
}
}
2.执行销毁逻辑
这里的DisposableBean就是注册到disposableBeans 集合里的DisposableBeanAdapter
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
// ...
@Override
public void destroy() {
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
// 执行@PreDestroy,自定义销毁方法的处理器
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
if (this.invokeDisposableBean) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((DisposableBean) this.bean).destroy();
return null;
}, this.acc);
}
else {
((DisposableBean) this.bean).destroy();
}
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
if (methodToInvoke != null) {
invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
}
}
}
}
总结销毁逻辑
- 如果有@PreDestroy就执行。
- 如果有自定义销毁后置处理器,执行处理方法。
- 如果实现了DisposableBean就执行destroy方法。
- 如果有destroyMethod 就执行。
public void destroySingletons() {
if (logger.isTraceEnabled()) {
logger.trace("Destroying singletons in " + this);
}
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]);
}
//清空inner bean依赖的beanName集合
this.containedBeanMap.clear();
//清空bean 被其他bean依赖的beanName集合
this.dependentBeanMap.clear();
//清空bean 依赖的其他bean的beanName集合
this.dependenciesForBeanMap.clear();
//清空单例池,及其他容器
clearSingletonCache();
}
至此,单例Bean的生命结束。