什么时候被称为spring beans destroy-method?
我在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; } }
配置文件:
您的示例不起作用,因为您没有关闭appcontext,您只是让程序终止。
在上下文中调用close()
,您将看到正在调用的bean destroy方法。
对于OP来说可能为时已晚,但如果有人还在寻找它……
close方法是在AbstractApplicationContext
而不是ApplicationContext
,另一种方法是使用ctx.registerShutdownHook()
instead of ctx.close()
,原因很明显,在运行Junit
你可能想关闭上下文而不是在生产环境中这样做让Spring决定何时关闭它。
//Getting application context ApplicationContext context = new ClassPathXmlApplicationContext(beansXML); //cleaning context ((ClassPathXmlApplicationContext) context).close();
仅当且仅当bean是单例实例时才调用“destroy-method”
请参阅IOC容器的日志输出
信息:在org.springframework.beans.factory.support.DefaultListableBeanFactory@1a0ce4c中销毁单例 :定义bean [book1]; 工厂层级的根
您需要将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"); } }
factory.destroySingletons();
在bean.display()
之后,在bean定义中对destroy-method
bean.display()
。 创建bean的默认范围是singleton因此,调用factory.destroySingletons()
将调用destroy-method
提到destroy-method
。