Есть ли способ иметь @Lazy
loading @Component
s что еще @Autowired
на заводе через аннотации? Проблема, которую я обнаружил, заключается в том, что, автолюбив свои ленивые компоненты на заводе, все они будут созданы сразу после загрузки фабрики, отрицая ленивую аннотацию.Лучший способ добиться @Autowired @Lazy @Components через аннотации?
Я определили несколько ленивые бобы, такие как
@Component
@Lazy
public final class CloseableChromeWebDriver
extends ChromeDriver
implements DisposableBean {
...
}
@Component
@Lazy
public final class CloseableFirefoxWebDriver
extends FirefoxDriver
implements DisposableBean {
...
}
Важно, чтобы они были ленивы, потому что
- Всякий раз, когда один из них создается, в окне браузера всплывает.
- Мои тесты, управляемые данными, могут требовать или не требовать ни одного или всех из них, то есть один запуск может быть всем Firefox, или может потребоваться Firefox и Chrome.
- это более важно, потому что на самом деле у меня есть шесть таких бобы - Firefox, Chrome, IE, удаленный Firefox, удаленный Chrome, удаленный IE.
- Итак, если в моих тестах используется только один из них, то я хочу, чтобы этот браузер показывал не все.
У меня есть завод для получения запрошенной браузера, но моя первая попытка это не удалось, потому что всякий раз, когда какой-либо класс, используемый на заводе, все autowired бобы были экземпляры сразу, независимо от того, были ли они на самом деле требуется. Я понимаю, это потому, что как только экземпляр класса создается, он должен создать экземпляр всех принадлежащих ему переменных экземпляра.
@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.
}
}
Так вот мой второй подход, который заключается в обеспечении отложенной загрузки, запрашивая боб через контекст приложения:
@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' распространяется на пользователя компонента, а не на определение компонента. Поэтому я ожидаю, что вы повесите '@ Lazy' всюду, которая нуждается в том, чтобы bean был ленивый загружен. Если это ВЕЗДЕ, тогда компонент будет создан при первом использовании. –
@AshleyFrieze Если я не понял, что вы говорите, ни один '@ Lazy' не переходит к пользователю компонента. Из [@Lazy Javadoc] (http://docs.spring.io/spring/docs /current/javadoc-api/org/springframework/context/annotation/Lazy.html): _ Может использоваться для любого класса, прямо или косвенно аннотированного с помощью @Component или методов, аннотированных с помощью @Bean ....Если присутствует и задано значение true, @Bean или @Component не будут инициализированы до тех пор, пока не будет указан другой компонент или явно извлечен из прилагаемого BeanFactory._ –
@AshleyFrieze, весной 4, вы на самом деле правы, как ответ Биджу. так что спасибо. :) –