spring源码注册需要销毁的bean registerDisposableBeanIfNecessary

21 篇文章 1 订阅
11 篇文章 0 订阅

前篇文章传送门
咱们上篇了解bean的初始化,

大家可以想下,bean为什么要销毁?

  1. 用完不再使用的bean
  2. 指定了destroy方法的bean执行destroy方法
  3. 容器关闭
  4. spring把需要销毁的bean注册到哪里呢?disposableBeans = new LinkedHashMap<>();
  5. 在何时进行销毁的?
registerDisposableBeanIfNecessary 注册需要被销毁的bean
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.
			// 注册需要被销毁的bean,如果满足 DestructionAwareBeanPostProcessors、实现了DisposableBean或者自定义销毁方法
			registerDisposableBean(beanName,new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
		}
		else {
			// A bean with a custom scope...
			// 这里需要自定义销毁 比如spring给咱们提供好了示例 MyTestScope
			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));
		}
	}
}
requiresDestruction(bean, mbd) 判断是否必须要销毁

满足包含销毁方法或者是DestructionAwareBeanPostProcessors

protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
		return (bean.getClass() != NullBean.class &&
				(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() && DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors())))
				);
	}
applicationContext.close(); 销毁

当容器关闭的时候会执行doClose()方法,然后执行destroyBeans(),然后再调用destroySingletons,最后把缓存中(Map)的bean进行移除掉

public void close() {
	synchronized (this.startupShutdownMonitor) {
		//当执行销毁容器时执行
		doClose();
		if (this.shutdownHook != null) {
			try {
				// 这里就是把后台线程给关闭了
				Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
			}catch (IllegalStateException ex) {
				// ignore - VM is already shutting down
			}
		}
	}
}
protected void doClose() {
	// 设置关闭状态
	if (this.active.get() && this.closed.compareAndSet(false, true)) {
		LiveBeansView.unregisterApplicationContext(this);
		try {
			// 关闭事件
			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);
			}
		}
		// 先进行执行销毁的方法
		destroyBeans();
		// 在关闭beanFactory 就是无引用关系
		closeBeanFactory();
		// 自定义扩展
		onClose();
		// 清空监听器
		if (this.earlyApplicationListeners != null) {
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}
		// 设置启动状态为关闭
		this.active.set(false);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 第一部分spring的核心 第1章开始spring之旅 1.1spring是什么 1.2开始spring之旅 1.3理解依赖注入 1.3.1依赖注入 1.3.2di应用 1.3.3企业级应用中的依赖注入 1.4应用aop 1.4.1aop介绍 1.4.2aop使用 1.5小结 第2章基本bean装配 2.1容纳你的bean 2.1.1beanfactory介绍 2.1.2使用应用上下文 2.1.3bean的生命 2.2创建bean 2.2.1声明一个简单的bean 2.2.2通过构造函数注入 2.3注入bean属性 2.3.1注入简单的数值 2.3.2使用其他的bean 2.3.3装配集合 2.3.4装配空值 2.4自动装配 2.4.1四种自动装配类型 2.4.2混合使用自动和手动装配 2.4.3何时采用自动装配 2.5控制bean创建 2.5.1bean范围化 2.5.2利用工厂方法来创建bean 2.5.3初始化和销毁bean 2.6小结 第3章高级bean装配 3.1声明父bean和子bean 3.1.1抽象基bean类型 3.1.2抽象共同属性 3.2方法注入 3.2.1基本的方法替换 3.2.2获取器注入 3.3注入非springbean 3.4注册自定义属性编辑器 3.5使用spring的特殊bean 3.5.1后处理bean 3.5.2bean工厂的后处理 3.5.3配置属性的外在化 3.5.4提取文本消息 3.5.5程序事件的解耦 3.5.6让bean了解容器 3.6脚本化的bean 3.6.1给椰子上lime 3.6.2脚本化bean 3.6.3注入脚本化bean的属性 3.6.4刷新脚本化bean 3.6.5编写内嵌的脚本化bean 3.7小结 第4章通知bean 4.1aop简介 4.1.1定义aop术语 4.1.2spring对aop的支持 4.2创建典型的spring切面 4.2.1创建通知 4.2.2定义切点和通知者 4.2.3使用proxyfactorybean 4.3自动代理 4.3.1为spring切面创建自动代理 4.3.2自动代理@aspectj切面 4.4定义纯粹的pojo切面 4.5注入aspectj切面 4.6小结 第二部分企业spring 第5章使用数据库 5.1spring的数据访问哲学 5.1.1了解spring数据访问的异常体系 5.1.2数据访问的模板化 5.1.3使用dao支持类 5.2配置数据 5.2.1使用jndi数据 5.2.2使用数据连接池 5.2.3基于jdbc驱动的数据 5.3在spring里使用jdbc 5.3.1处理失控的jdbc代码 5.3.2使用jdbc模板 5.3.3使用spring对jdbc的dao支持类 5.4在spring里集成hibernate 5.4.1选择hibernate的版本 5.4.2使用hibernate模板 5.4.3建立基于hibernate的dao 5.4.4使用hibernate3上下文会话 5.5spring和java持久api 5.5.1使用jpa模板 5.5.2创建一个实体管理器工厂 5.5.3建立使用jpa的dao 5.6spring和ibatis 5.6.1配置ibatis客户模板 5.6.2建立基于ibatis的dao 5.7缓存 5.7.1配置缓存方案 5.7.2缓存的代理bean 5.7.3注解驱动的缓存 5.8小结 第6章事务管理 6.1理解事务 6.1.1仅用4个词解释事务 6.1.2理解spring对事务管理的支持 6.2选择事务管理器 6.2.1jdbc事务 6.2.2hibernate事务 6.2.3jpa事务 6.2.4jdo事务 6.2.5jta事务 6.3在spring中编写事务 6.4声明式事务 6.4.1定义事务参数 6.4.2代理事务 6.4.3在spring2.0里声明事务 6.4.4定义注释驱动事务 6.5小结 第7章保护spring 7.1springsecurity介绍 7.2验证用户身份 7.2.1配置providermanager 7.2.2根据数据库验证身份 7.2.3根据ldap仓库进行身份验证 7.3控制访问 7.3.1访问决策投票 7.3.2决定如何投票 7.3.3处理投票弃权 7.4保护web应用程序 7.4.1代理springsecurity的过滤器 7.4.2处理安全上下文 7.4.3
Spring框架中,Bean的生命周期可以分为以下几个阶段: 1. 实例化(Instantiation):容器创建Bean的实例。 2. 属性赋值(Populate):容器将Bean的属性值设置到对应的属性中。 3. 初始化(Initialization):容器调用Bean的初始化方法。 4. 使用(In Use):Bean被容器使用。 5. 销毁(Destruction):容器销毁Bean的实例。 下面我们来详细介绍一下这些阶段。 1. 实例化 Bean的实例化可以通过两种方式实现: (1)使用构造函数创建Bean的实例。 (2)使用工厂方法创建Bean的实例。 无论使用哪种方式,一旦Bean实例化完成,Spring容器就会拥有该Bean的实例对象。 2. 属性赋值 属性赋值是指将Bean的属性值设置到对应的属性中。Spring框架提供了三种方式实现属性赋值: (1)通过构造函数注入。 (2)通过Setter方法注入。 (3)通过自动装配注入。 其中,自动装配注入分为byName、byType、constructor、autodetect四种方式。 3. 初始化 初始化是指在Bean实例化并完成属性赋值后,Spring容器会调用Bean的初始化方法进行一些额外的设置或操作。初始化方法包括两种: (1)实现InitializingBean接口的afterPropertiesSet()方法。 (2)在Bean配置文件中使用init-method属性指定初始化方法。 4. 使用 使用阶段是指Spring容器将Bean实例注入到需要使用该实例的地方,比如注入到其他Bean中。 5. 销毁 销毁阶段是指Spring容器在销毁Bean实例前会调用Bean销毁方法进行一些清理工作。销毁方法包括两种: (1)实现DisposableBean接口的destroy()方法。 (2)在Bean配置文件中使用destroy-method属性指定销毁方法。 以上就是SpringBean的生命周期,通过了解Bean的生命周期,我们可以更好地理解Spring的运行机制,并且可以更好地使用Spring框架进行开发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值