Spring源码分析之Bean的生命周期(下)

本文深入探讨了Spring中Bean的生命周期,包括Aware接口、初始化前后处理、@PostConstruct、DisposableBean接口及其销毁方法。通过实例展示了每个阶段的执行顺序和逻辑,详细解释了如何在各个阶段定制Bean的行为。
摘要由CSDN通过智能技术生成

接上:Spring中Bean的生命周期(上)

五、初始化相关

执行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的流程,而是直接调用初始化后的方法完成初始化后的操作。

Created with Raphaël 2.2.0 开始创建bean 1.实例化前 bean==null ? 2.实例化 3.填充属性 4.Aware 5.初始化前 6.初始化 7.初始化后 完成创建 yes no
	@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));
			}
		}
	}

}

总结销毁逻辑

  1. 如果有@PreDestroy就执行。
  2. 如果有自定义销毁后置处理器,执行处理方法。
  3. 如果实现了DisposableBean就执行destroy方法。
  4. 如果有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的生命结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值