when is a spring beans destroy-method called?
I have put a sysout statement in the "destroy-method" for a bean. When i run a sample code, the sysout is not getting output. Does that mean the destroy-method is not getting called ?
The Test Class:
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();
}
}
The 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 setP开发者_运维问答rop1");
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;
}
}
The Config file:
<?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>
Your example doesn't work because you're not shutting down the appcontext, you're just letting the program terminate.
Call close()
on the context, and you'll see the bean destroy-methods being called.
It may be too late for the OP, but if someone is still looking for it...
The close method is in AbstractApplicationContext
and not ApplicationContext
, also another way is to use ctx.registerShutdownHook()
instead of ctx.close()
for obvious reasons that while running Junit
s you might want to close the context but not while in production environment so let Spring decide on when to close it.
The "destroy-method" is only called if and only if the bean is a singleton instance
See the log output of the IOC container
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1a0ce4c: defining beans [book1]; root of factory hierarchy
//Getting application context
ApplicationContext context = new ClassPathXmlApplicationContext(beansXML);
//cleaning context
((ClassPathXmlApplicationContext) context).close();
hi you need to change ApplicationContext
to AbstractApplicationContext
and then register to a ShutDownhook
which will destroy your bean and also implement the DisposableBean interface eg:
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();
}
}
and now implemnt the DisposableBean interface
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();
after your bean.display()
as destroy-method
is valued in the bean definition. The default scope with which bean is created is singleton hence, invoking the factory.destroySingletons()
will call the method mentioned in the destroy-method
.
精彩评论