J'ai mis une déclaration sysout dans la méthode "destroy" pour un haricot. Lorsque je lance un exemple de code, le sysout ne reçoit pas de sortie. Cela signifie-t-il que la méthode de destruction n'est pas appelée?
La classe de test:
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();
}
}
Le haricot
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;
}
}
Le fichier de configuration:
<?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>
Votre exemple ne fonctionne pas car vous ne fermez pas l'appcontext, vous laissez simplement le programme se terminer.
Appelez close()
sur le contexte et vous verrez que les méthodes de destruction de haricots sont appelées.
Il est peut-être trop tard pour le PO, mais si quelqu'un le recherche toujours ...
La méthode de fermeture est en AbstractApplicationContext
et non pas ApplicationContext
. Une autre méthode consiste à utiliser ctx.registerShutdownHook()
instead of ctx.close()
pour des raisons évidentes voulant que lors de l'exécution de Junit
s, vous souhaitiez peut-être fermer le contexte mais pas en environnement de production, laissez donc Spring décider du moment où le fermer.
//Getting application context
ApplicationContext context = new ClassPathXmlApplicationContext(beansXML);
//cleaning context
((ClassPathXmlApplicationContext) context).close();
La "méthode-de-destruction" n'est appelée que si et seulement si le bean est une instance singleton
Voir la sortie du journal du conteneur IOC
INFO: Détruire des singletons dans org.springframework.beans.factory.support.DefaultListableBeanFactory@1a0ce4c: définition des haricots [book1]; racine de la hiérarchie d'usine
salut, vous devez changer ApplicationContext
en AbstractApplicationContext
puis vous inscrire à un ShutDownhook
qui détruira votre bean et implémentera également l’interface DisposableBean, par exemple:
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();
}
}
et maintenant implémenter l'interface 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");
}
}
factory.destroySingletons();
après votre bean.display()
en tant que destroy-method
est évalué dans la définition du bean. La portée par défaut avec laquelle le bean est créé est singleton. Par conséquent, l'appel de factory.destroySingletons()
appellera la méthode mentionnée dans destroy-method
.