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. PHP设计模式:观察者模式

    示例代码详见https://github.com/52fhy/design_patterns 观察者模式 观察者模式(Observer)是对象的行为模式,又叫发布-订阅(Publish/Subscri ...

  2. Linux安装go语言开发包

    1.下载go语言安装包,eg:go1.7.1.linux-amd64.tar.gz2.安装go语言 $ cd /home/xm6f/dev $ tar -zxvf go1.7.1.linux-amd6 ...

  3. Linux-(ping,traceroute,ss)

    ping命令 1.命令格式: ping [参数] [主机名或IP地址] 2.命令功能: ping命令用于:确定网络和各外部主机的状态:跟踪和隔离硬件和软件问题:测试.评估和管理网络.如果主机正在运行并 ...

  4. Linux ulimit和动态修改MySQL最大线程数限制

    ulimit是限制进程对资源的使用但软件资源限制变化不大,特别是process/file,分别对应nproc和nofilenproc可用 ulimit -u 查询:nofile可用 ulimit -n ...

  5. Solidity字符串类型

    字符串可以通过""或者''来表示字符串的值,Solidity中的string字符串不像C语言一样以\0结束,比如abcd这个字符串的长度就为我们所看见的字母的个数,它的长度为4. ...

  6. java 正则例子

    1.不易开头.结尾:小数:圆角字符 包含数字.字母.圆角字符 不以<br/>开头.结尾,但中间可以存在 小数中的小数点是半角 正则表达式 "^(?!<br/>)(([ ...

  7. 超简单MVC应用程序播放WMV视频

    本篇博文,介绍给大家的是,在MVC应用程序中,播放Windows media video(.wmv) 视频文件. Insus.NET的实现方法,把media player组件,嵌入MVC的控制器的Co ...

  8. C#读取“我的文档”等特殊系统路径及环境变量

    返回“我的文档”路径字符串 Environment.GetFolderPath(Environment.SpecialFolder.Personal) 本技巧使用GetFolderPath方法来获取指 ...

  9. python安装过程的一些问题解决方案

    1. pip升级后出现提示信息 DEPRECATION: The default format will switch to columns in the future. You can use –f ...

  10. 乐字节-Java8新特性-接口默认方法之Stream流(下)

    接上一篇:<Java8新特性之stream>,下面继续接着讲Stream 5.流的中间操作 常见的流的中间操作,归为以下三大类:筛选和切片流操作.元素映射操作.元素排序操作: 操作 描述 ...