web-dev-qa-db-ja.com

アノテーションを介して@Autowired @Lazy @Componentsを実現する最良の方法は?

@Lazyがまだ@Componentである@Autowiredsをファクトリーにアノテーション経由でロードする方法はありますか?私が見つけた問題は、ファクトリで遅延コンポーネントを自動配線することにより、ファクトリがロードされるとすぐにすべてがインスタンス化され、遅延注釈が無効になることです。

私は次のようないくつかの遅延豆を定義しました

@Component
@Lazy
public final class CloseableChromeWebDriver
      extends ChromeDriver
      implements DisposableBean {
...
}

@Component
@Lazy
public final class CloseableFirefoxWebDriver
      extends FirefoxDriver
      implements DisposableBean {
...
}

怠け者であることが重要です

  • それらのいずれかが作成されるたびに、ブラウザウィンドウがポップアップします。
  • 私のデータ駆動型テストは、それらのいずれかまたはすべてを必要とする場合もあれば、必要としない場合もあります。
  • 実際には、Firefox、Chrome、IE、リモートFirefox、リモートChrome、リモートIEのような6つのBeanがあるため、これはより重要です。
  • そのため、テストでそのうちの1つのみを使用する場合、すべてではなく、その1つのブラウザーのみを表示する必要があります。

要求されたブラウザーを取得するためのファクトリーがありますが、クラスをファクトリーで使用するたびに、実際に要求されたかどうかに関係なく、すべての自動配線されたBeanがすぐにインスタンス化されるため、これに対する最初の試みは失敗しました。これは、クラスがインスタンス化されると、そのクラスに属するすべてのインスタンス変数をインスタンス化する必要があるためです。

@Component
public final class WebDriverFactory {
   @Autowired
   private CloseableChromeWebDriver chromeWebDriver;
   @Autowired
   private CloseableFirefoxWebDriver firefoxWebDriver;

   public synchronized WebDriver getWebDriver(final Browser browser) {
     // get whatever webdriver is matched by the enum Browser.
   }
}

したがって、アプリケーションコンテキストを介してBeanを要求することで遅延読み込みを保証する2番目のアプローチを次に示します。

@Component
public final class WebDriverFactory {
   private CloseableChromeWebDriver chromeWebDriver;
   private CloseableFirefoxWebDriver firefoxWebDriver;
   @Autowired
   private ApplicationContext appContext;

   public synchronized WebDriver getWebDriver(final Browser browser) {
      WebDriver driver = null;
      switch (browser) {
         case FIREFOX:
            if (firefoxRemoteWebDriver == null) {
               firefoxRemoteWebDriver = appContext.getBean("closeableRemoteFirefoxWebDriver",
                     CloseableRemoteFirefoxWebDriver.class);
            }
            driver = firefoxRemoteWebDriver;
            break;
      // etc...
      return driver;
   }
}

このアプローチは私の目標を達成しますが、アノテーションを使用することの有用性を実際に無効にすると感じています。これを達成するための純粋に注釈ベースの方法はありますか?

  • JDK 6
  • Spring 3.2.6.RELEASE
  • Xmlなし、注釈のみ。
29

あなたは〜を持つ必要があります @Lazyアノテーションもコンポーネント上の@Autowired in。これは、@Lazyをコンポーネントに追加すると、Beanとして熱心に作成されます。また、@Lazyあなたの@Autowiredその後、再び熱心に作成され、Beanに注入されます。だから、次を試してみて、それはちょうどうまくいくはずです:

@Component
public final class WebDriverFactory {
   @Autowired @Lazy
   private CloseableChromeWebDriver chromeWebDriver;
   @Autowired @Lazy
   private CloseableFirefoxWebDriver firefoxWebDriver;
49
Biju Kunjummen