1. Bean标签的destroy-method方法

配置数据源的时候,会有一个destroy-method方法

  1. <bean id = "dataSource" class = "org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  2. <property name="driverClassName" value="${jdbc.driver}"></property>
  3. <property name="url" value="${jdbc.url}"></property>
  4. <property name="username" value="${jdbc.username}"></property>
  5. <property name="password" value="${jdbc.password}"></property>
  6. <property name="maxActive" value="${maxActive}"></property>
  7. <property name="maxWait" value="${maxWait}"></property>
  8. <property name="maxIdle" value="30"></property>
  9. <property name="initialSize" value="2"></property>
  10. </bean>

这个destroy-method属性是干什么用的。什么时候调用呢?
Spring中的doc上是这么说destroy-method方法的---

  1. The name of the custom destroy method to invoke on bean factory shutdown.
  2. The method must have no arguments, but may throw any exception. Note:
  3. Only invoked on beans whose lifecycle is under the full control of the factory - which
  4. is always the case for singletons, but not guaranteed for any other scope.

其实,这是依赖在Servlet容器或者EJB容器中,它才会被自动给调用的。比如我们用Servlet容器,经常在web.xml文件中配置这样的监听器

  1. <listener>
  2. <listener-class>
  3. org.springframework.web.context.ContextLoaderListener
  4. </listener-class>
  5. </listener>

我们按层次包,看一下ContextLoaderListener这个类。

  1. public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
  2. //这个是web容器初始化调用的方法。
  3. public void contextInitialized(ServletContextEvent event) {
  4. this.contextLoader = createContextLoader();
  5. if (this.contextLoader == null) {
  6. this.contextLoader = this;
  7. }
  8. this.contextLoader.initWebApplicationContext(event.getServletContext());
  9. }
  10. //这个是web容器销毁时调用的方法。
  11. public void contextDestroyed(ServletContextEvent event) {
  12. if (this.contextLoader != null) {
  13. this.contextLoader.closeWebApplicationContext(event.getServletContext());
  14. }
  15. ContextCleanupListener.cleanupAttributes(event.getServletContext());
  16. }
 

ContextLoaderListener实现了javax.servlet.ServletContextListener,它是servlet容器的监听器接口。
ServletContextListener接口中定义了两个方法。

  1. public void contextInitialized(ServletContextEvent event);
  2. public void contextDestroyed(ServletContextEvent event);

分别在容器初始化或者销毁的时候调用。
那么当我们销毁容器的时候,其实就是调用的contextDestroyed方法里面的内容。
这里面执行了ContextLoader的closeWebApplicationContext方法。

  1. public void closeWebApplicationContext(ServletContext servletContext) {
  2. servletContext.log("Closing Spring root WebApplicationContext");
  3. try {
  4. if (this.context instanceof ConfigurableWebApplicationContext) {
  5. ((ConfigurableWebApplicationContext) this.context).close();
  6. }
  7. }
  8. finally {
  9. ClassLoader ccl = Thread.currentThread().getContextClassLoader();
  10. if (ccl == ContextLoader.class.getClassLoader()) {
  11. currentContext = null;
  12. }
  13. else if (ccl != null) {
  14. currentContextPerThread.remove(ccl);
  15. }
  16. servletContext.removeAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
  17. if (this.parentContextRef != null) {
  18. this.parentContextRef.release();
  19. }
  20. }
  21. }

这里面,将context转型为ConfigurableWebApplicationContext,而
ConfigurableWebApplicationContext继承自ConfigurableApplicationContext,在ConfigurableApplicationContext(ConfigurableApplicationContext实现了Lifecycle,正是前文提到的lifecycle)里有
close()方法的定义。在AbstractApplicationContext实现了close()方法。真正执行的是

  1. protected void destroyBeans() {
  2. getBeanFactory().destroySingletons();
  3. }

方法(spring容器在启动的时候,会创建org.apache.commons.dbcp.BasicDataSource的对象,放入singleton缓存中。那么在容器销毁的时候,会清空缓存并调用BasicDataSourc中的close()方法。
)
BasicDataSourc类中的close()方法

  1. public synchronized void close() throws SQLException {
  2. GenericObjectPool oldpool = connectionPool;
  3. connectionPool = null;
  4. dataSource = null;
  5. try {
  6. if (oldpool != null) {
  7. oldpool.close();
  8. }
  9. } catch(SQLException e) {
  10. throw e;
  11. } catch(RuntimeException e) {
  12. throw e;
  13. } catch(Exception e) {
  14. throw new SQLNestedException("Cannot close connection pool", e);
  15. }
  16. }

那么,如果spring不在Servlet或者EJB容器中,我们就需要手动的调用AbstractApplicationContext类中的close()方法,去实现相应关闭的功能。

转:http://www.xuebuyuan.com/1628117.html 谢!

Spring中的destroy-method方法的更多相关文章

  1. Spring中RestTemplate的使用方法

    一.REST 在互联网中,我们会通过请求url来对网络上的资源做增删改查等动作,这里的请求包含两部分:动词,主要包括增.删.改.查:名词,就是网络中的各种资源.传统的非REST风格的请求方式是把动词和 ...

  2. 面试官:spring中定义bean的方法有哪些?我一口气说出了12种,把面试官整懵了。

    前言 在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜.我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工 ...

  3. 【Spring Framework】12种spring中定义bean的方法

    前言 在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜.我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工 ...

  4. SSM-Spring-12:Spring中NameMatchMethodPointcutAdvisor名称匹配方法切入点顾问

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- advice 是通知advisor 是顾问 顾问(Advisor) 通知Advice是Spring提供的一种切 ...

  5. spring中的多线程aop方法拦截

    日常开发中,常用spring的aop机制来拦截方法,记点日志.执行结果.方法执行时间啥的,很是方便,比如下面这样:(以spring-boot项目为例) 一.先定义一个Aspect import org ...

  6. Spring中@Async注解实现“方法”的异步调用

    原文:http://www.cnblogs.com/zhengbin/p/6104502.html 简单介绍: Spring为任务调度与异步方法执行提供了注解支持.通过在方法上设置@Async注解,可 ...

  7. spring中得到servletContext对象方法

    1.spring得到servletContext,这个和session没有什么关系,上下文可以说是一个session容器,一个上下文可以有多个会话session 在web.xml中有以下配置后.加入s ...

  8. spring 中StoredProcedure的使用方法

    StoredProcedure是一个抽象类,必须写一个子类来继承它,这个类是用来简化JDBCTemplate运行存储过程操作的. 首先我们写一个实现类: package com.huaye.frame ...

  9. Spring中使用Ehcache的方法和注意事项

    如何调用方法数据增加缓存 @Cacheable(value="MY_CACHE", key="'cache_business_' + #business_id" ...

  10. Spring中获取Session的方法汇总

    Spring: web.xml <listener> <listener-class>org.springframework.web.context.request.Reque ...

随机推荐

  1. Tensorflow应用之LSTM

    学习RNN时原理理解起来不难,但是用TensorFlow去实现时被它各种数据的shape弄得晕头转向.现在就结合一个情感分析的案例来了解一下LSTM的操作流程. 一.深度学习在自然语言处理中的应用 自 ...

  2. postgresql主从配置

    master:10.0.1.114 slaver:10.0.1.116 一.yum安装https://blog.csdn.net/weixin_41048363/article/details/803 ...

  3. Haproxy 重定向跳转设置 - 运维小结

    前面已经详细介绍了Haproxy基础知识 , 今天这里再赘述下Haproxy的重定向跳转的设置.  haproxy利用acl来实现haproxy动静分离,然而在许多运维应用环境中,可能需要将访问的站点 ...

  4. Docker轻量级web图形页面管理 - Portainer部署记录

    Docker图形页面管理工具基本常用的有三种: Docker UI,Shipyard,Portainer,之前分别介绍了Docker UI和Shipyard部署,下面简单介绍下Portainer部署. ...

  5. NYOJ 1013 除法表达式(欧几里德算法+唯一分解定理)

    题目链接: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=1013 描述 给出一个这样的除法表达式:X1/X2/X3/···/Xk,其中Xi是 ...

  6. C#Redis 事务操作

    一.理论 还是抄前辈的理论知识. 和众多其它数据库一样,Redis作为NoSQL数据库也同样提供了事务机制.在Redis中,MULTI/EXEC/DISCARD/WATCH这四个命令是我们实现事务的基 ...

  7. [转]Magento2开发教程 - 如何向数据库添加新表

    本文转自:https://www.cnblogs.com/xz-src/p/6920365.html Magento 2具有特殊的机制,允许你创建数据库表,修改现有的,甚至添加一些数据到他们(如安装数 ...

  8. MVC应用程序显示Flash(swf)视频

    前段时间, Insus.NET有实现<MVC使用Flash来显示图片>http://www.cnblogs.com/insus/p/3598941.html 在演示中,它也可以显示Flas ...

  9. Java多线程--基础概念

    Java多线程--基础概念 必须知道的几个概念 同步和异步 同步方法一旦开始,调用者必须等到方法调用返回后,才能执行后续行为:而异步方法调用,一旦开始,方法调用就立即返回,调用者不用等待就可以继续执行 ...

  10. SQL Server优化查询

    1. 首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个 10万条记录的表中查1条 ...