24

我在 bean 的“destroy-method”中添加了一个 sysout 语句。当我运行示例代码时,sysout 没有得到输出。这是否意味着销毁方法没有被调用?

测试类:

  package spring.test;

  import org.springframework.context.ApplicationContext;
  import org.springframework.context.support.ClassPathXmlApplicationContext;

  public class InitTest {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("InitTestContext.xml");
        InitTestBean bean = (InitTestBean)ctx.getBean("InitTestBean");
        bean.display();
    }
  }

豆子

  package spring.test;

  public class InitTestBean {
    private String prop1;
    private String prop2;

    public InitTestBean(String prop1, String prop2) {
        System.out.println("Instantiating InitTestBean");
        this.prop1 = prop1;
        this.prop2 = prop2;
    }

    public void setProp1(String prop1) {
        System.out.println("In setProp1");
        this.prop1 = prop1;
    }

    public void setProp2(String prop2) {
        System.out.println("In setProp2");
        this.prop2 = prop2;
    }

    public String getProp1() {
        return prop1;
    }

    public String getProp2() {
        return prop2;
    }

    public void display() {
        System.out.println("Prop1 is " + prop1);
        System.out.println("Prop2 is " + prop2);
    }

    public void initialize(){
        System.out.println("In initialize");
        this.prop1 = "init-prop1";
        this.prop2 = "init-prop2";
    }

    public void teardown() {
        System.out.println("In teardown");
        this.prop1 = null;
        this.prop2 = null;
    }
  }

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="InitTestBean" class="spring.test.InitTestBean" init-method="initialize" destroy-method="teardown">
        <constructor-arg value="Prop1" />
        <constructor-arg value="Prop2" />
        <property name="prop1" value="setProp1"/>
        <property name="prop2" value="setProp2"/>
    </bean>

</beans>
4

6 回答 6

37

您的示例不起作用,因为您没有关闭 appcontext,您只是让程序终止。

调用close()上下文,您将看到调用了 bean destroy-methods。

于 2010-12-16T12:12:29.717 回答
24

对于OP来说可能为时已晚,但如果有人仍在寻找它......

close 方法是 inAbstractApplicationContext和 not ApplicationContext,另一种方法是使用ctx.registerShutdownHook() instead of ctx.close(),原因很明显,在运行Junits 时您可能想要关闭上下文,但在生产环境中却不想,所以让 Spring 决定何时关闭它。

于 2012-04-24T20:09:39.977 回答
6
//Getting application context
ApplicationContext context = new ClassPathXmlApplicationContext(beansXML); 

//cleaning context
((ClassPathXmlApplicationContext) context).close(); 
于 2012-10-25T20:31:04.583 回答
5

仅当且仅当 bean 是单例实例时才调用“destroy-method”

查看IOC容器的日志输出

信息:在 org.springframework.beans.factory.support.DefaultListableBeanFactory@1a0ce4c 中销毁单例:定义 bean [book1];工厂层次结构的根

于 2013-10-16T08:29:13.827 回答
2

嗨,您需要更改ApplicationContextAbstractApplicationContext然后注册到ShutDownhook将销毁您的 bean 并实现 DisposableBean 接口,例如:

  package spring.test;

  import org.springframework.context.ApplicationContext;
  import org.springframework.context.support.ClassPathXmlApplicationContext;
  import org.springframework.context.support.AbstractApplicationContext;
  public class InitTest {
    public static void main(String[] args) {
       AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("InitTestContext.xml");
  ctx.registerShutdownHook();
        InitTestBean bean = (InitTestBean)ctx.getBean("InitTestBean");
        bean.display();
    }
  }

现在实现 DisposableBean 接口

package spring.test;
import org.springframework.beans.factory.DisposableBean;
  public class InitTestBean implements DisposableBean{
    private String prop1;
    private String prop2;
    public InitTestBean(String prop1, String prop2) {
        System.out.println("Instantiating InitTestBean");
        this.prop1 = prop1;
        this.prop2 = prop2;
    }
    public void setProp1(String prop1) {
        System.out.println("In setProp1");
        this.prop1 = prop1;
    }
    public void setProp2(String prop2) {
        System.out.println("In setProp2");
        this.prop2 = prop2;
    }
    public String getProp1() {
        return prop1;
    }
    public String getProp2() {
        return prop2;
    }
    public void display() {
        System.out.println("Prop1 is " + prop1);
        System.out.println("Prop2 is " + prop2);
    }
    public void initialize(){
        System.out.println("In initialize");
        this.prop1 = "init-prop1";
        this.prop2 = "init-prop2";
    }
    public void teardown() {
        System.out.println("In teardown");
        this.prop1 = null;
        this.prop2 = null;
    }
    @Override
    public void destroy() throws Exception {

        System.out.println(" the bean has been destroyed");
    }
  }
于 2013-03-18T07:07:10.450 回答
1

factory.destroySingletons();在您的bean.display()asdestroy-method在 bean 定义中被重视之后。创建 bean 的默认作用域是单例,因此factory.destroySingletons()调用destroy-method.

于 2013-06-18T15:29:29.423 回答