2017-06-24 12 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()); 
    } 

} 

を、私は(すなわちmyFoo.shutdown();Fooのメソッドを呼び出す必要がありますMyConf1が破壊されたとき。 (ApplicationContext.getBean()を介して)アプリケーションコンテキストから直接Beanインスタンスを取得せずにこの操作を実行する方法はありますか?

ケース2再び

、の第二Spring構成クラスを考えてみましょう:

@Configuration 
public class MyConf2 { 

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

} 

今回は、私がMyConf2を破壊する前jobTimer.cancel()を起動する必要があります。実際には、をscheduledJob()の外側にインスタンス化するか、メソッドのパラメータとしてscheduledJob(Timer jobTimer)とすることができます。 MyConf2のための適切なデストロイヤー方法を定義することが可能になります。しかし、他の方法があるかどうかを知りたい。

良い提案がありますか?

注:FooBarTimerScheduledJobクラスが外部で定義されています。したがって、内部破壊メソッドを明示的に定義する可能性はありません。前提として、MyConf1MyConf2だけを変更できます。

答えて

-1

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

DisposableBeanは、ケース#1のお手伝いをする必要があります以下のページをご覧ください。

+0

私の質問をよくお読みください。あなたが言及したスレッドは、2番目のケースをカバーしています。私はすでに 'destroy'メソッドをどのように使用できるかについて説明しました。しかし、実際に可能であれば(関連する説明とともに)、私は他のアプローチを探しています。 – vdenotaris

0

私は、Fooクラス同様

に(@PreDestroyで注釈さ)destroy()メソッドを定義示唆

public class ScheduledJob { 

    private Timer timer; 

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

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

ようScheduledJobクラスを変更し、@Bean

@Configuration 
public class MyConf2 { 

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

} 
+0

'Foo'クラスと' ScheduledJob'クラスは外部で定義されているはずなので、明示的にdestroyメソッドを定義することはできません。 – vdenotaris

0

destroyMethodのparamを追加することになりますを実装できますそうでない場合は、この方法requiresDestructionはtrueを返す必要があることに

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

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

ご注意:Beanはそのインタフェースdestroy.Inときにできるインタフェースは前-破壊コールバックを追加し、方法postProcessBeforeDestructionはそれを行うで、以下を参照してください。メソッドpostProcessBeforeDestructionは、Beanを破棄するときは呼び出されません。

と私がテストしている:Beanがdestroy.The出力されたときpostProcessBeforeDestructionが本当に

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

を呼び出すには、次のとおりです。

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をxmlファイルの 'Component'アノテーションまたはconfigを使用してアプリケーション内に作成してください。アプリケーションは、破棄されたときに各Beanに対してこれらのメソッドを呼び出します。 – dabaicai

+0

申し訳ありませんが、私が*行動を拡張する*と言ったときには、この点を明確にするために*クラスを拡張する*という意味ではありません。 :)しかし、私は指定されたクラスをそのまま使用することを想定しなければなりません。 – vdenotaris

関連する問題