有没有办法通过注释,在工厂中仍然自动装配作为@Component
的@Lazy
加载组件?我发现的问题是,通过在工厂中自动装配我的懒惰组件,它们在工厂加载时将立即全部实例化,从而抵消了懒惰注释。
我已定义了几个延迟加载的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、远程 Firefox、远程 Chrome、远程 IE。
- 因此,如果我的测试只使用其中一个浏览器,那么我只希望显示该浏览器,而不是所有浏览器。
我有一个用于获取请求浏览器的工厂,但我第一次尝试失败了,因为每当任何类使用该工厂时,所有自动装配的 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,仅有注释。
- JDK 6
- Spring 3.2.6.RELEASE
- 无需XML,仅需要注解。
@Lazy
不会放在bean的用户上。从@Lazy Javadoc中可以看到:可以用于任何直接或间接注释为@Component的类或使用@Bean注释的方法...如果存在并设置为true,则@Bean或@Component将不会在被另一个bean引用或从封闭的BeanFactory中显式检索之前初始化。 - Robert Mark Bram