web-dev-qa-db-ja.com

Spring ControllerのInitメソッド(注釈バージョン)

コントローラーを新しいアノテーションバージョンに変換しています。古いバージョンでは、次を使用してspringmvc-servlet.xmlでinitメソッドを指定していました。

<beans>
    <bean id="myBean" class="..." init-method="init"/>
</beans>

注釈バージョンを使用してinitメソッドを指定するにはどうすればよいですか?

103
Krt_Malta

使用できます

@PostConstruct
public void init() {
   // ...
}
225
Johan Sjöberg

あるいは、クラスに InitializingBean インターフェースを実装させて、Beanの構築時にApplicationContextが呼び出すコールバック関数(afterPropertiesSet())を提供することもできます。

20
matt b

Springで初期化プロセスをインターセプトする方法はいくつかあります。すべてのBeanを初期化し、それらを自動配線/インジェクトする必要がある場合、これを保証する少なくとも2つの方法があります。私は2番目のテストのみを持っていますが、私は両方とも同じように動作します。

@Beanを使用している場合、次のようにinitMethodで参照できます。

@Configuration
public class BeanConfiguration {

  @Bean(initMethod="init")
  public BeanA beanA() {
    return new BeanA();
  }
}

public class BeanA {

  // method to be initialized after context is ready
  public void init() {
  }

} 

@Componentを使用している場合、このような@EventListenerで注釈を付けることができます。

@Component
public class BeanB {

  @EventListener
  public void onApplicationEvent(ContextRefreshedEvent event) {
  }
}

私の場合、レガシシステムがあり、現在はSpring Bootが選択されたフレームワークであるIoC/DIを使用しています。古いシステムは、テーブルに多くの循環依存関係をもたらします。したがって、setter-dependencyを多く使用する必要があります。セッターによる自動配線/インジェクションがまだ行われていないため、@ PostConstructを信頼できなかったため、頭痛の種になりました。順序はコンストラクターで、@ PostConstructは自動設定セッターです。すべてのBeanに対して「同じ」時間に最後に実行される@EventListenerアノテーションで解決しました。この例は、InitializingBeanの実装も示しています。

相互に依存する2つのクラス(@Component)があります。これらのクラスの1つだけを表示するこの例の目的では、クラスは同じように見えます。

@Component
public class BeanA implements InitializingBean {
  private BeanB beanB;

  public BeanA() {
    log.debug("Created...");
  }

  @PostConstruct
  private void postConstruct() {
    log.debug("@PostConstruct");
  }

  @Autowired
  public void setBeanB(BeanB beanB) {
    log.debug("@Autowired beanB");
    this.beanB = beanB;
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    log.debug("afterPropertiesSet()");
  }

  @EventListener
  public void onApplicationEvent(ContextRefreshedEvent event) {
    log.debug("@EventListener");
  } 
}

これは、コンテナの起動時の呼び出しの順序を示すログ出力です。

2018-11-30 18:29:30.504 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : Created...
2018-11-30 18:29:30.509 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : Created...
2018-11-30 18:29:30.517 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @Autowired beanA
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : afterPropertiesSet()
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @Autowired beanB
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : afterPropertiesSet()
2018-11-30 18:29:30.607 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @EventListener
2018-11-30 18:29:30.607 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @EventListener

ご覧のとおり、すべての準備ができて構成された後、@ EventListenerが最後に実行されます。

2
Avec