resource injection how ejemplo dependency annotation java spring lazy-loading

java - how - spring injection constructor



¿La mejor forma de lograr @Autowired @Lazy @Components a través de anotaciones? (1)

¿Hay alguna manera de tener @Lazy cargando @Component s que todavía estén @Autowired en una fábrica a través de anotaciones? El problema que encontré es que al autoautilizar mis componentes perezosos en la fábrica, todos se crearán una instancia inmediatamente una vez que se cargue la fábrica, negando la anotación perezosa.

He definido varios frijoles perezosos como

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

Es importante que sean perezosos porque

  • Cada vez que se crea uno de ellos, aparece la ventana del navegador.
  • mis pruebas basadas en datos pueden o no requerir una o todas, es decir, una ejecución puede ser todo Firefox, o puede requerir Firefox y Chrome.
  • esto es más importante porque, de hecho, tengo seis de esos beans: Firefox, Chrome, IE, Remote Firefox, Remote Chrome, Remote IE.
  • Entonces, si mis pruebas solo usan una de ellas, entonces solo quiero que se muestre ese navegador, no todas.

Tengo una Fábrica para obtener el navegador solicitado, pero mi primer intento fracasó porque siempre que alguna clase usaba la fábrica, todos los frijoles con conexión automática se creaban de inmediato, independientemente de si realmente se habían solicitado. Entiendo que esto se debe a que una vez que se crea una instancia de la clase, debe crear una instancia de todas las variables de instancia que le pertenecen.

@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. } }

Así que aquí está mi segundo enfoque, que es asegurar la carga perezosa al solicitar el bean a través del contexto de la aplicación:

@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; } }

Este enfoque logra mi objetivo, pero siento que realmente niega la utilidad de usar anotaciones. ¿Hay una forma puramente basada en anotaciones para lograr esto?

  • JDK 6
  • Primavera 3.2.6.RELEASE
  • No xml, solo anotaciones.

@Lazy tener la anotación @Lazy en su componente también en el punto donde está @Autowired . Esto se debe a que si no tiene @Lazy en su componente, entonces se crea con entusiasmo como un bean, y si tiene no tenga un @Lazy en su @Autowired , una vez más, se crea con entusiasmo y se inyecta en el frijol. Así que intente lo siguiente y debería funcionar:

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