2017-06-24 26 views
1

案例1如何正确地摧毁一个Spring配置类

让我们考虑下面的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()); 
    } 

} 

由于种种原因,我需要调用一个Foo的方法(即myFoo.shutdown();)当MyConf1被销毁。 有没有什么办法可以在没有直接从应用程序上下文中检索bean实例的情况下执行这个操作(通过ApplicationContext.getBean())?

案例2

再次,让我们考虑第二Spring配置类:

@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定义适当的驱逐舰方法。但是,我想知道是否还有其他方法可以继续。

有什么好的建议吗?

注:FooBarTimerScheduledJob类外部定义。因此,不可能明确定义内部销毁方法。作为假设,我只能修改MyConf1MyConf2

回答

-1
+0

请仔细阅读我的问题:

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

当bean是destroy.The输出是postProcessBeforeDestruction真的叫。你提到的线程只是第二种情况,我已经解释过如何使用'destroy'方法。然而,正如所说的,我正在寻找其他方法,如果的确有可能(与相关的解释)。 – vdenotaris

0

我建议在Foo

同样定义destroy()方法(与@PreDestroy注释),修改ScheduledJob类像

public class ScheduledJob { 

    private Timer timer; 

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

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

而且在@Bean

@Configuration 
public class MyConf2 { 

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

} 
+0

'Foo'和'ScheduledJob'类应该是外部定义的,因此不可能明确定义一个销毁方法。 – vdenotaris

0

添加destroyMethod PARAM你可以执行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应返回true,否则当bean应该销毁时,方法postProcessBeforeDestruction不会调用。

,我有一个测试:

before destory:[email protected] 
before destory:[email protected] 
before destory:[email protected] 
before destory:[email protected] 
before destory:[email protected] 
before destory:[email protected]482e36 
before destory:[email protected]7fbd92c 
+0

这种方法对我来说不是很清楚。如上所述,我没有机会扩展'Foo','ScheduledJob'和'Timer'的行为(至少,没有使用像* Adapter *这样的适当的设计模式)。基本上我可以直接修改的唯一类是'MyConf1'和'MyConf2'。 – vdenotaris

+0

不扩展,只需为接口上方的实现创建一个新的类,然后在应用程序中创建一个该类的bean,使用'Component'注释或在xml文件中配置该bean。该bean只在应用程序中注册回调,应用程序将在销毁时为每个bean调用这些方法。 – dabaicai

+0

对不起,当我说*扩展行为*我不是说*扩展一个类*,只是为了澄清这一点。 :)但是,我必须假设使用给定的类,就像它们一样,没有任何包装(我知道,我故意让它很难)。 – vdenotaris