Вопрос по spring, destroy, javabeans, java – Не могли бы вы добавить больше деталей или объяснений? Ваш текущий ответ настолько скуден, что может быть удален.

21

естил выражение sysout в "метод уничтожения" для компонента. Когда я запускаю пример кода, 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();
    }
  }

Боб

  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>
Должно быть какэтот Jigar Joshi
Метод destroy работает просто отлично. Покажите нам свой код и конфиг. skaffman
Если у вас слишком много бинов с инициализацией и / или уничтожением методов с одинаковыми именами, вам не нужно объявлять init-method и destroy-method для каждого отдельного бина. С помощьюdefault-init-method, default-destroy-метод атрибуты на<бобы> элемент Phat H. VU
У тебя не было триггера, чтобы сообщить Spring, что ты закрываешься. Как отмечали другие, вам нужно сообщить об этом, чем закрывать среду в целом. asgs

Ваш Ответ

6   ответов
1

привет тебе надо поменятьApplicationContext вAbstractApplicationContext а затем зарегистрироваться наShutDownhook который уничтожит ваш компонент, а также реализует интерфейс 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");
    }
  }
29

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

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

Это здорово, но есть ли способ попросить SpringJUnit4ClassRunner сделать это для вас? У меня есть десятки тестовых классов, использующих это, и бегун класса, похоже, не закрывает контекст после завершения своих тестов. Это расстраивает, так как при каждом запуске по отдельности они успешны, но при запуске в целом (через пакет mvn) они терпят неудачу после того, как достаточное количество из них запущено, даже не закрыв должным образом соединения. Lucas
java_geek: это не на этом интерфейсе, это на реализации:ClassPathXmlApplicationContext skaffman
@java_geek: Да, это так. Это на одном из его суперклассов. skaffman
даже classpathxmlapplicationcontext не имеет метода close. java_geek
В ApplicationContext нет метода закрытия. java_geek
4
//Getting application context
ApplicationContext context = new ClassPathXmlApplicationContext(beansXML); 

//cleaning context
((ClassPathXmlApplicationContext) context).close(); 
Таким образом, это работает. Gondy
1

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

Не могли бы вы добавить больше деталей или объяснений? Ваш текущий ответ настолько скуден, что может быть удален. Keith Pinson
23

Это может быть слишком поздно для OP, но если кто-то все еще ищет это ...

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

+ 1. Проверьте это:tutorialspoint.com/spring/spring_bean_life_cycle.htm Phat H. VU
+1 Это должен быть принятый ответ. user1019830
@vsriram Вы можете создать свой собственный поток или runnable, который обрабатывает это, вызывая ctx.close (), когда ваши условия случаются. В противном случае он не будет вызываться сам по себе, пока ваш сервер и jvm работают efaj
Есть ли способ закрыть его автоматически по таймауту. Скажем, я держал мое приложение на моем сервере в течение недели. Это закроется в какой-то момент? Будет ли вызван метод destroy в это время? vsriram92
3

когда компонент является экземпляром-одиночкой

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

ИНФОРМАЦИЯ:Уничтожение синглетонов в org.s[email protected]1a0ce4c: определение бинов [book1]; корень фабричной иерархии

Это был настоящий ответ для меня. Я изо всех сил пытался понять, почемуclose а такжеregisterShutdownHook не работали. Jonathan Benn

Похожие вопросы