java - 通过注释实现@Autowired @Lazy @Components 的最佳方法?

标签 java spring lazy-loading

有没有办法让 @Lazy 加载 @Component 仍然是 @Autowired 在工厂通过注解?我发现的问题是,通过在工厂中 Autowiring 我的惰性组件,一旦加载了工厂,它们都会立即实例化,否定惰性注释。

我已经定义了几个惰性bean,例如

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

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

他们懒惰很重要,因为

  • 只要创建其中一个,就会弹出浏览器窗口。
  • 我的数据驱动测试可能需要也可能不需要其中任何一项或全部,即一次运行可能全部是 Firefox,或者可能需要 Firefox 和 Chrome。
  • 这更重要,因为事实上我有六个这样的 bean - Firefox、Chrome、IE、Remote Firefox、Remote Chrome、Remote IE。
  • 所以,如果我的测试只使用其中一个,那么我只希望显示那个浏览器,而不是全部显示。

我有一个工厂来获取请求的浏览器,但我的第一次尝试失败了,因为每当任何类使用工厂时,所有 Autowiring 的 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 来确保延迟加载:

@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,只有注释。

最佳答案

你必须在你的组件上有 @Lazy 注释,以及它在 @Autowired 所在的位置。这是因为如果你没有 @Lazy 在你的组件上,然后它被急切地创建为一个 bean,如果你的 @Autowired 上没有 @Lazy 然后它再次被急切地创建并注入(inject)到 bean 中。因此,请尝试以下操作,它应该可以正常工作:

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

关于java - 通过注释实现@Autowired @Lazy @Components 的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26504224/

相关文章:

java - 将字符串数组转换为 double 组

java - 实时观察数百万个微小物体

java - 将 BigDecimal 转换为数组中的字符串

java - 为什么我的弹出窗口与 ListView 发生冲突?

c# - 管理类之间的共享资源?

java - 在维护预先存在的 XML 映射的同时启用 Spring MVC 注释

java - 在 Eclipse 中关闭 hibernate 日志记录

spring - Autowiring LinkedBlockingQueue 时出现空指针异常

reactjs - 我应该对整个应用程序使用动态导入吗?

java - 初始化惰性集合