Existe-t-il un moyen d’avoir @Lazy
train de charger des @Component
s qui sont toujours @Autowired
dans une usine via des annotations? Le problème que j’ai trouvé est qu’en envoyant mes composants paresseux en usine, ils seront tous instanciés immédiatement après le chargement de la fabrique, annulant ainsi l’annotation différée.
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 Factory pour obtenir le navigateur demandé, mais ma première tentative a échoué car chaque fois qu’une classe utilisait la fabrique, tous les beans autowired étaient immédiatement instanciés, qu’ils aient été réellement demandés ou non. Je comprends que c’est parce qu’une fois la classe 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 à garantir un chargement paresseux en demandant le bean via le contexte d’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 objective, mais j’estime que cela nie vraiment l’utilité d’utiliser des annotations. Existe-t-il un moyen purement basé sur des annotations pour y parvenir?
Vous devez également avoir l’annotation @Lazy
sur votre composant au point où il est @Autowired
in. En effet, si vous n’avez pas @Lazy
sur votre composant, il est créé avec impatience sous la forme d’un haricot, et si n’avez pas de @Lazy
sur votre @Autowired
mais il est à nouveau créé et injecté avec impatience dans le haricot. Donc, essayez ce qui suit et cela devrait fonctionner:
@Component public final class WebDriverFactory { @Autowired @Lazy private CloseableChromeWebDriver chromeWebDriver; @Autowired @Lazy private CloseableFirefoxWebDriver firefoxWebDriver;