如何正确销毁 Spring 配置 class

How to properly destroy a Spring configuration class

案例一

让我们考虑以下 Spring 配置:

@Configuration
public class MyConf1 {

    @Bean
    public Foo getFoo() {
        // Foo class is defined as part of an external lib.
        return new Foo();
    }

    @Bean
    public Bar getBar() {
        return new Bar(getFoo());
    } 

 }

出于某些原因,我需要在 MyConf1 被销毁时调用 Foo 的方法(即 myFoo.shutdown();)。 有什么方法可以在不直接从应用程序上下文(通过 ApplicationContext.getBean())检索 bean 实例的情况下执行此操作?

案例二

同样,让我们​​考虑第二个 Spring 配置 class:

@Configuration
public class MyConf2 {

    @Bean
    public ScheduledJob scheduledJob() {
        Timer jobTimer = new Timer(true);
        return new ScheduledJob(jobTimer);
    }

 }

这一次,我需要在销毁MyConf2之前调用jobTimer.cancel()。实际上,我可以在 scheduledJob() 之外实例化 jobTimer,或者将其作为方法的参数,如 scheduledJob(Timer jobTimer)。 然后就可以为 MyConf2 定义一个合适的破坏者方法。但是,我想知道是否还有其他方法可以继续。

有什么好的建议吗?

注:FooBarTimerScheduledJobclass都是外部定义的。因此,不可能显式定义内部销毁方法。作为假设,我只能修改 MyConf1MyConf2

请看下页http://forum.spring.io/forum/spring-projects/container/48426-postconstruct-and-predestroy-in-javaconfig

DisposableBean 应该可以帮助您解决案例 #1。

我建议在 Foo class

中定义一个 destroy() 方法(用 @PreDestroy 注释)

类似地,将ScheduledJob class修改为

public class ScheduledJob {

    private Timer timer;

    public ScheduledJob(Timer timer){
        this.timer = timer;
    }

    @PreDestroy
    public void destroy(){
        timer.cancel();
    }
}

并在@Bean

中添加destroyMethod参数
@Configuration
public class MyConf2 {

    @Bean(destroyMethod = "destroy")
    public ScheduledJob scheduledJob() {
        Timer jobTimer = new Timer(true);
        return new ScheduledJob(jobTimer);
    }

}

你可以实现DestructionAwareBeanPostProcessor接口,当bean是destroy.In那个接口时,可以添加一个销毁前的回调,方法postProcessBeforeDestruction就是这样做的,看下面:

@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
    System.out.println("before destory:"+bean);
}

@Override
public boolean requiresDestruction(Object bean) {
    return true;
}

注意方法requiresDestruction必须return为真,否则bean应该销毁时方法postProcessBeforeDestruction不会调用

我有一个测试:

public static void main(String[] args){
    ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("classpath:application-main.xml");
    applicationContext.registerShutdownHook();
}

当 bean 为 destroy.The 时真正调用 postProcessBeforeDestruction 输出为:

before destory:com.zhuyiren.spring.learn.util.Handler@55141def
before destory:com.zhuyiren.spring.learn.controller.TestControleler@47eaca72
before destory:com.zhuyiren.spring.learn.service.impl.TestServiceImpl@7b2bbc3
before destory:com.zhuyiren.spring.learn.service.impl.TwoServiceImpl@48f2bd5b
before destory:com.zhuyiren.spring.learn.controller.ConverConroller@72967906
before destory:org.springframework.context.event.DefaultEventListenerFactory@1a482e36
before destory:org.springframework.context.event.EventListenerMethodProcessor@77fbd92c