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. 关于VS2017的安装和WDK的选择问题

    首先就是关于VS2017的安装,我们可以通过微软的官网去寻找我们想要安装的VS版本 我们可以随便选择一个我们需要的版本进行下载,任意版本的VS都可以. 然后下载安装的时候,要进行一下这个安装选项的选择 ...

  2. 搭建laravel到nginx

    一.laravel的安装 搭建的第一步当然是安装好laravel,这里推介composer安装,由于国内的问题,极其推介使用国内的镜像去搭建,我在终端里本已经设置好常规的https和http之类的FQ ...

  3. Spring注解 @Configuration

    Spring注解 @Configuration 一.@Configuration的作用 二.@Configuration的Spring容器启动方式 三.不加@Configuration的@Bean的解 ...

  4. 解决:git使用git push 命令跳出remote: Permission to A denied to B的问题

    开始git上传项目,不料,在git push这一步骤发生了错误? remote: Permission to qwe2193066947/firstRepository.git denied to m ...

  5. MVC用非Entity Framework将数据显示于视图(二)

    这篇<MVC用非Entity Framework将数据显示于视图> http://www.cnblogs.com/insus/p/3364235.html 也算是MVC视图显示数据库的数据 ...

  6. easyui datagrid 动态改变行背景色

    /*根据查询条件查询调度单列表*/ function InitGrid(queryData) { $("#dg").datagrid({ loadMsg: "数据加载中, ...

  7. 本地SQL数据库执行作业定时修改其他数据库内容

    --exec sp_addlinkedserver 'xkp', ' ', 'SQLOLEDB', '192.168.66.66'  定义链接--exec sp_addlinkedsrvlogin ' ...

  8. js实现iview表格 排名列

    (有误,请勿观看) 一.排名的简单实现 //排名例子1 //需要排名的数组 //var myArray = [5,7, 7, 9, 8, 6, 23]; //新数组 //var thisArray = ...

  9. Java生成代码(字节码)

    一.方式 代码生成器 & IDE 编译时代码生成: Pluggable Annotation Processing API 运行时代码生成: Compiler API 运行时生成字节码: cg ...

  10. POJ1811(SummerTrainingDay04-G miller-rabin判断素性 && pollard-rho分解质因数)

    Prime Test Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 35528   Accepted: 9479 Case ...