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. 因为错误关闭Selinux导致CentOS7启动失败(进度条卡死,图形界面加载卡死)

    我在CentOS7上安装oracle,非常麻烦,搞半天终于安装完毕,当天我没有发现任何问题,第二天上班打开虚拟机CentOS7就进不去了. 我想起来之前关闭了Selinux,把系统名称改成了redha ...

  2. T4模板根据数据库表和列的Description生成代码的summary的终极解决方案

    相信很多人都用T4模版生成代码,用T4模版生成标准代码真的很方便.我们经常根据表生成相关的代码, 但是估计很多人都遇见过同一个问题, 特别是我们在生成model的时候,代码中model中的Summar ...

  3. Docker基础-端口映射与容器互联

    1.端口映射实现访问容器 1.从外部访问容器应用 在启动容器的时候,如果不指定对应的参数,在容器外部是无法通过网络来访问容器内部的网络应用和服务的. 当容器中运行一些网络应用,要让外部访问这些应用时, ...

  4. [Angularjs]ng-bind-html指令

    摘要 在为html标签绑定数据的时,如果绑定的内容是纯文本,你可以使用{{}}或者ng-bind.但在为html标签绑定带html标签的内容的时候,angularjs为了安全考虑,不会将其渲染成htm ...

  5. ASP.NET截取网页注释行之间的内容

    这是网友在论坛问到的问题,网友要求:“我想要抓取每一个<!-- 文字新闻spider begin -->开始<!-- 文字新闻spider end -->      结尾的中间 ...

  6. 配置Windows 防火墙,允许SQL Server的远程连接

    在运行SQL Server的服务器上,我们要找到哪些是SQL Server正在侦听的端口,并将其添加到Windows防火墙的入站例外. 首先,我们需要添加 SQL Server 服务侦听 Window ...

  7. t3用户-角色-权限hibernate经典配置

    用户-角色-权限hibernate经典配置. 既然有人问起,我就写下说明吧.在文章中间的配置文件那里.权当回忆一下,也帮助更多人.这是以前学校时写的,没有注释.都是贴的代码笔记.看到的莫要见怪.欢迎学 ...

  8. Docker初次使用与安装过程

    Docker入门 Docker 简介 Docker有两个版本: 社区版(CE) 企业版(EE) Docker Community Edition(CE)非常适合希望开始使用Docker并尝试使用基于容 ...

  9. JavaScriptDay2-简单网页表单验证

    Html部分 <!-- 注册表单 1-用户名 text 2-密码 password 3-确认密码 password 4-性别 radio 5-爱好 hobby 6-籍贯 select-optio ...

  10. Mybatis插件开发

    前面几篇文章介绍了Mybtis中四个重要的对象,其中提到它们都是在Configuration中被创建的,我们一起看一下创建四大对象的方法,代码如下所示: public ParameterHandler ...