Подтвердить что ты не робот

Когда вызывается spring beans метод уничтожения?

Я поставил инструкцию sysout в "destroy-method" для bean. Когда я запускаю пример кода, sysout не получает выход. Означает ли это, что метод destroy не вызван?

Класс тестирования:

  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();
    }
  }

Bean

  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>
4b9b3361

Ответ 1

Ваш пример не работает, потому что вы не закрываете appcontext, вы просто позволяете программе завершить работу.

Вызовите close() в контексте, и вы увидите вызовы bean destroy-methods.

Ответ 2

Возможно, слишком поздно для OP, но если кто-то все еще ищет его...

Метод close находится в AbstractApplicationContext, а не ApplicationContext, также другим способом является использование ctx.registerShutdownHook() instead of ctx.close() по очевидным причинам, что при запуске Junit вам может понадобиться закрыть контекст, но не во время производства поэтому пусть Spring решит, когда его закрыть.

Ответ 3

//Getting application context
ApplicationContext context = new ClassPathXmlApplicationContext(beansXML); 

//cleaning context
((ClassPathXmlApplicationContext) context).close(); 

Ответ 4

"destroy-method" вызывается только тогда и только тогда, когда bean является одиночным экземпляром

См. вывод журнала контейнера IOC

INFO: Уничтожение синглонов в org.s[email protected]1a0ce4c: определение beans [book1]; root из factory иерархии

Ответ 5

hi вам нужно изменить ApplicationContext на AbstractApplicationContext, а затем зарегистрироваться на 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");
    }
  }

Ответ 6

factory.destroySingletons(); после того, как ваш bean.display() как destroy-method оценивается в определении bean. Область по умолчанию, с которой создается bean, является singleton, поэтому вызов factory.destroySingletons() вызовет метод, упомянутый в destroy-method.