2017-06-24 28 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