Existe-t-il un moyen d'avoir @Lazy
chargement @Component
s qui sont encore @Autowired
dans une usine via des annotations? Le problème que j'ai trouvé est qu'en câblant automatiquement mes composants paresseux en usine, ils seront tous instanciés immédiatement une fois l'usine chargée, annulant l'annotation paresseuse.
J'ai défini plusieurs haricots paresseux tels que
@Component
@Lazy
public final class CloseableChromeWebDriver
extends ChromeDriver
implements DisposableBean {
...
}
@Component
@Lazy
public final class CloseableFirefoxWebDriver
extends FirefoxDriver
implements DisposableBean {
...
}
Il est important qu'ils soient paresseux car
J'ai une usine pour obtenir le navigateur demandé, mais ma première tentative a échoué car chaque fois qu'une classe utilisait l'usine, tous les beans câblés automatiquement étaient instanciés immédiatement, qu'ils aient été réellement demandés ou non. Je comprends que c'est parce qu'une fois que la classe est instanciée, elle doit instancier toutes les variables d'instance qui lui appartiennent.
@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.
}
}
Voici donc ma deuxième approche qui consiste à assurer un chargement paresseux en demandant le bean via le contexte de l'application:
@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;
}
}
Cette approche atteint mon objectif, mais je pense qu'elle nie vraiment l'utilité d'utiliser des annotations. Existe-t-il un moyen purement basé sur des annotations pour y parvenir?
Tu dois avoir @Lazy
annotation sur votre composant également au point où il se trouve @Autowired
in. C'est parce que si vous n'avez pas @Lazy
sur votre composant, il est alors créé avec empressement en tant que bean, et si vous n'avez pas de @Lazy
Sur ton @Autowired
puis à nouveau, il est créé avec impatience et injecté dans le haricot. Essayez donc ce qui suit et cela devrait fonctionner:
@Component
public final class WebDriverFactory {
@Autowired @Lazy
private CloseableChromeWebDriver chromeWebDriver;
@Autowired @Lazy
private CloseableFirefoxWebDriver firefoxWebDriver;